From 446e918e1474dd9647caf83b488b0cef35c3327d Mon Sep 17 00:00:00 2001 From: btharper Date: Wed, 31 Oct 2018 22:01:26 -0400 Subject: [PATCH 001/340] Convert strings to Decimal values Punt string handling to python Decimal object, this correctly represents both integers and floats (except with regards to trailing zeros) Change command line tests to reflect handling of ints --- num2words/__init__.py | 2 ++ num2words/base.py | 3 +++ tests/test_cli.py | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index aaf40dfa..a2c18b6d 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -96,6 +96,8 @@ 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) diff --git a/num2words/base.py b/num2words/base.py index 3b990e34..c73f741b 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -96,6 +96,9 @@ def parse_minus(self, num_str): return '%s ' % self.negword, 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 diff --git a/tests/test_cli.py b/tests/test_cli.py index 3e1d3abc..638331a8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -72,7 +72,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): @@ -82,7 +82,7 @@ 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): From 8fde057760575b1b62f281ce1330e01f2a22b316 Mon Sep 17 00:00:00 2001 From: Marek Madejski Date: Mon, 3 Dec 2018 09:57:37 +0100 Subject: [PATCH 002/340] Update lang_PL.py - typo in "kwadryliard" - expanded long scale up to decilliard (10^63) - PEP8 compliance --- num2words/lang_PL.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 42891777..f9377c4b 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -70,16 +70,27 @@ } 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: ('kwaryliard', 'kwadryliardy', 'kwadryliardów'), # 10^27 - 10: ('kwintylion', 'kwintyliony', 'kwintylionów'), # 10^30 + 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 } From f26c3a139aeadd74a2608d8c760181399aa97d68 Mon Sep 17 00:00:00 2001 From: Marek Madejski Date: Mon, 3 Dec 2018 11:05:36 +0100 Subject: [PATCH 003/340] Update test_pl.py test for really big number's Polish name --- tests/test_pl.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_pl.py b/tests/test_pl.py index c8a8462b..0dbd97d6 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -64,6 +64,22 @@ def test_cardinal(self): "osiemdziesiąt cztery miliony dwieście dwadzieścia " "tysięcy dwieście dziewięćdzisiąt jeden" ) + self.assertEqual( + num2words( + 963301000001918264129471042047146102350812074235000101020000120324, + lang='pl' + ), + "dziewięćset sześćdziesiąt trzy decyliardy trzysta jeden " + "decylionów nonylion dziewięćset osiemnaście oktyliardów dwieście " + "sześćdziesiąt cztery oktyliony sto dwadzieścia dziewięć " + "septyliardów czterysta siedemdziesiąt jeden septylionów " + "czterdzieści dwa sekstyliardy czterdzieści siedem sekstylionów " + "sto czterdzieści sześć kwintyliardów sto dwa kwintyliony trzysta " + "pięćdziesiąt kwadryliardów osiemset dwanaście kwadrylionów " + "siedemdziesiąt cztery tryliardy dwieście trzydzieści pięć " + "trylionów sto jeden bilionów dwadzieścia miliardów sto " + "dwadzieścia tysięcy trzysta dwadzieścia cztery" + ) def test_to_ordinal(self): # @TODO: implement to_ordinal From 52fb935d8cf9570b977dbb2970f51356656b27dd Mon Sep 17 00:00:00 2001 From: Marek Madejski Date: Fri, 28 Dec 2018 11:57:12 +0100 Subject: [PATCH 004/340] PL: regular names for powers of thousand Names for powers of thousand are now built instead of being hardcoded - less error-prone and more concise. --- num2words/lang_PL.py | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 4b97a5fd..2fa52f79 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -17,6 +17,8 @@ from __future__ import unicode_literals +import itertools + from .base import Num2Word_Base from .utils import get_digits, splitbyx @@ -71,29 +73,27 @@ } 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 + 1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3 } +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 = { From 778786b65b5468f60a36d24394125893dfc643be Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sat, 12 Jan 2019 19:10:31 +0100 Subject: [PATCH 005/340] fix ordinal_num for French numbers ending with 1 (#236) --- num2words/lang_FR.py | 2 +- tests/test_fr.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/num2words/lang_FR.py b/num2words/lang_FR.py index 4524cb56..85ef87ed 100644 --- a/num2words/lang_FR.py +++ b/num2words/lang_FR.py @@ -89,7 +89,7 @@ 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): diff --git a/tests/test_fr.py b/tests/test_fr.py index 1299dcc1..6170cb70 100644 --- a/tests/test_fr.py +++ b/tests/test_fr.py @@ -107,10 +107,13 @@ 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') ) From 0398d164600c57e48f41697d588ef4150c40a9bb Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sun, 13 Jan 2019 23:04:10 +0100 Subject: [PATCH 006/340] German: 2 more ordinal tests --- tests/test_de.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_de.py b/tests/test_de.py index d20794db..2715e7f6 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -23,7 +23,10 @@ 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") From df65296a80140ab645a251e8ab6f04cefeb04ca9 Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sun, 13 Jan 2019 23:18:51 +0100 Subject: [PATCH 007/340] German: similar rule for million as for 100 and 1000; 2 more ordinal tests --- num2words/lang_DE.py | 2 ++ tests/test_de.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/num2words/lang_DE.py b/num2words/lang_DE.py index f6816979..23c6f68c 100644 --- a/num2words/lang_DE.py +++ b/num2words/lang_DE.py @@ -118,6 +118,8 @@ def to_ordinal(self, value): # Exception: "hundertste" is usually preferred over "einhundertste" if res == "eintausendste" or res == "einhundertste": res = res.replace("ein", "", 1) + if res == "eine millionste": + res = res.replace("eine ", "", 1) return res diff --git a/tests/test_de.py b/tests/test_de.py index 2715e7f6..3b451af3 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -47,6 +47,9 @@ def test_ordinal_at_crucial_number(self): self.assertEqual( num2words(4000, ordinal=True, lang='de'), "viertausendste" ) + self.assertEqual( + num2words(1000000, ordinal=True, lang='de'), "millionste" + ) self.assertEqual( num2words(2000000, ordinal=True, lang='de'), "zwei millionste" ) @@ -57,6 +60,7 @@ def test_ordinal_at_crucial_number(self): def test_cardinal_at_some_numbers(self): self.assertEqual(num2words(100, lang='de'), "einhundert") + 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") From e321caf392ac9c61b89301c33926068deb046ff5 Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sun, 13 Jan 2019 23:25:54 +0100 Subject: [PATCH 008/340] Million etc. are upper case in German --- num2words/lang_DE.py | 4 ++-- tests/test_de.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/num2words/lang_DE.py b/num2words/lang_DE.py index 23c6f68c..ced83128 100644 --- a/num2words/lang_DE.py +++ b/num2words/lang_DE.py @@ -45,7 +45,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", @@ -118,7 +118,7 @@ def to_ordinal(self, value): # Exception: "hundertste" is usually preferred over "einhundertste" if res == "eintausendste" or res == "einhundertste": res = res.replace("ein", "", 1) - if res == "eine millionste": + if res == "eine Millionste": res = res.replace("eine ", "", 1) return res diff --git a/tests/test_de.py b/tests/test_de.py index 3b451af3..f8ab13e4 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -48,22 +48,22 @@ def test_ordinal_at_crucial_number(self): num2words(4000, ordinal=True, lang='de'), "viertausendste" ) self.assertEqual( - num2words(1000000, ordinal=True, lang='de'), "millionste" + num2words(1000000, ordinal=True, lang='de'), "Millionste" ) self.assertEqual( - num2words(2000000, ordinal=True, lang='de'), "zwei millionste" + num2words(2000000, ordinal=True, lang='de'), "zwei Millionste" ) self.assertEqual( num2words(5000000000, ordinal=True, lang='de'), - "fünf milliardste" + "fünf Milliardste" ) def test_cardinal_at_some_numbers(self): self.assertEqual(num2words(100, lang='de'), "einhundert") - 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") + 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( @@ -73,8 +73,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): From b71facf3ea377ed8bdc1278ea010f3af05f3dd2c Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sun, 13 Jan 2019 23:55:34 +0100 Subject: [PATCH 009/340] German: ordinals involving 'Million' etc. are written without space, and lower case --- num2words/lang_DE.py | 13 ++++++++++--- tests/test_de.py | 9 ++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/num2words/lang_DE.py b/num2words/lang_DE.py index ced83128..348b44f5 100644 --- a/num2words/lang_DE.py +++ b/num2words/lang_DE.py @@ -17,6 +17,8 @@ from __future__ import print_function, unicode_literals +import re + from .lang_EU import Num2Word_EU @@ -107,7 +109,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,8 +120,13 @@ def to_ordinal(self, value): # Exception: "hundertste" is usually preferred over "einhundertste" if res == "eintausendste" or res == "einhundertste": res = res.replace("ein", "", 1) - if res == "eine Millionste": - res = res.replace("eine ", "", 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 diff --git a/tests/test_de.py b/tests/test_de.py index f8ab13e4..7635cfb5 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -48,14 +48,17 @@ def test_ordinal_at_crucial_number(self): num2words(4000, ordinal=True, lang='de'), "viertausendste" ) self.assertEqual( - num2words(1000000, ordinal=True, lang='de'), "Millionste" + num2words(1000000, ordinal=True, lang='de'), "millionste" ) self.assertEqual( - num2words(2000000, ordinal=True, lang='de'), "zwei Millionste" + 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): From 67d58e708131cb12de2d2f1df46d614696123342 Mon Sep 17 00:00:00 2001 From: Zeno Gantner Date: Sun, 13 Jan 2019 23:57:57 +0100 Subject: [PATCH 010/340] German: add 3 more test cases for thousands --- tests/test_de.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_de.py b/tests/test_de.py index 7635cfb5..2e50e5c3 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -63,6 +63,9 @@ def test_ordinal_at_crucial_number(self): def test_cardinal_at_some_numbers(self): self.assertEqual(num2words(100, lang='de'), "einhundert") + 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") From 2eee037648eb2245d9714f694e4868b80082a216 Mon Sep 17 00:00:00 2001 From: Ernesto Rodriguez Ortiz Date: Sat, 19 Jan 2019 16:53:07 -0500 Subject: [PATCH 011/340] Fix typo 'seperator' on source code --- num2words/base.py | 6 +++--- num2words/lang_ES.py | 4 ++-- num2words/lang_FI.py | 4 ++-- num2words/lang_HE.py | 2 +- num2words/lang_JA.py | 2 +- num2words/lang_KO.py | 2 +- num2words/lang_PT.py | 4 ++-- num2words/lang_SR.py | 6 +++--- tests/test_cz.py | 6 +++--- tests/test_en.py | 18 +++++++++--------- tests/test_lv.py | 12 ++++++------ tests/test_nl.py | 8 ++++---- tests/test_pl.py | 6 +++--- tests/test_ru.py | 10 +++++----- tests/test_sr.py | 10 +++++----- tests/test_uk.py | 12 ++++++------ 16 files changed, 56 insertions(+), 56 deletions(-) diff --git a/num2words/base.py b/num2words/base.py index de281165..025e0145 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -263,14 +263,14 @@ def _cents_verbose(self, number, currency): 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 @@ -297,7 +297,7 @@ def to_currency(self, val, currency='EUR', cents=True, seperator=',', minus_str, self.to_cardinal(left), self.pluralize(left, cr1), - seperator, + separator, cents_str, self.pluralize(right, cr2) ) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 482a4141..b1aafa67 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -168,10 +168,10 @@ 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") 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_HE.py b/num2words/lang_HE.py index d98a84a7..c1d71a3c 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -131,7 +131,7 @@ def n2w(n): return int2word(int(n)) -def to_currency(n, currency='EUR', cents=True, seperator=','): +def to_currency(n, currency='EUR', cents=True, separator=','): raise NotImplementedError() diff --git a/num2words/lang_JA.py b/num2words/lang_JA.py index 928dddf5..58a29460 100644 --- a/num2words/lang_JA.py +++ b/num2words/lang_JA.py @@ -491,7 +491,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_KO.py b/num2words/lang_KO.py index e192cc64..e4e01b5b 100644 --- a/num2words/lang_KO.py +++ b/num2words/lang_KO.py @@ -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_PT.py b/num2words/lang_PT.py index 3c47b17a..6f459726 100644 --- a/num2words/lang_PT.py +++ b/num2words/lang_PT.py @@ -215,13 +215,13 @@ 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 diff --git a/num2words/lang_SR.py b/num2words/lang_SR.py index 919cad03..74ff0f04 100644 --- a/num2words/lang_SR.py +++ b/num2words/lang_SR.py @@ -173,14 +173,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 +210,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/tests/test_cz.py b/tests/test_cz.py index 4d237a75..660919b0 100644 --- a/tests/test_cz.py +++ b/tests/test_cz.py @@ -84,11 +84,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 +97,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_en.py b/tests/test_en.py index b477c5fc..15080877 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -71,54 +71,54 @@ 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" ) diff --git a/tests/test_lv.py b/tests/test_lv.py index a0bffe9a..754ca621 100644 --- a/tests/test_lv.py +++ b/tests/test_lv.py @@ -106,12 +106,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 +122,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..52ae6781 100644 --- a/tests/test_nl.py +++ b/tests/test_nl.py @@ -69,24 +69,24 @@ def test_ordinal_for_floating_numbers(self): def test_to_currency(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') diff --git a/tests/test_pl.py b/tests/test_pl.py index abc34b9b..ec76ed8c 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -106,12 +106,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 +120,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_ru.py b/tests/test_ru.py index 9c35b767..f2415aea 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -170,22 +170,22 @@ def test_to_currency(self): ) self.assertEqual( num2words(10111, lang='ru', to='currency', currency='EUR', - seperator=' и'), + separator=' и'), 'сто один евро и одиннадцать центов' ) self.assertEqual( num2words(10121, lang='ru', to='currency', currency='RUB', - seperator=' и'), + separator=' и'), 'сто один рубль и двадцать одна копейка' ) self.assertEqual( num2words(10122, lang='ru', to='currency', currency='RUB', - seperator=' и'), + separator=' и'), 'сто один рубль и двадцать две копейки' ) self.assertEqual( num2words(10121, lang='ru', to='currency', currency='EUR', - seperator=' и'), + separator=' и'), 'сто один евро и двадцать один цент' ) self.assertEqual( @@ -194,7 +194,7 @@ def test_to_currency(self): 'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов' ) self.assertEqual( - num2words('38.4', lang='ru', to='currency', seperator=' и', + num2words('38.4', lang='ru', to='currency', separator=' и', cents=False, currency='EUR'), "тридцать восемь евро и 40 центов" ) diff --git a/tests/test_sr.py b/tests/test_sr.py index 8547325b..c97a0930 100644 --- a/tests/test_sr.py +++ b/tests/test_sr.py @@ -203,7 +203,7 @@ def test_to_currency(self): lang='sr', to='currency', currency='EUR', - seperator=' i' + separator=' i' ) ) self.assertEqual( @@ -213,18 +213,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 +238,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_uk.py b/tests/test_uk.py index ff171036..69342120 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -100,27 +100,27 @@ def test_to_currency(self): ) # self.assertEqual( # num2words(10111, lang='uk', to='currency', currency='EUR', - # seperator=u' та'), + # separator=u' та'), # "сто один євро та одинадцять центiв" # ) self.assertEqual( num2words(10121, lang='uk', to='currency', currency='UAH', - seperator=u' та'), + separator=u' та'), "сто одна гривня та двадцять одна копiйка" ) self.assertEqual( num2words(10121, lang='uk', to='currency', currency='UAH', - seperator=u' та'), + separator=u' та'), "сто одна гривня та двадцять одна копiйка" ) self.assertEqual( num2words(10122, lang='uk', to='currency', currency='UAH', - seperator=u' та'), + separator=u' та'), "сто одна гривня та двадцять двi копiйки" ) # self.assertEqual( # num2words(10121, lang='uk', to='currency', currency='EUR', - # seperator=u' та'), + # separator=u' та'), # "сто один євро та двадцять один цент" # ) self.assertEqual( @@ -129,7 +129,7 @@ def test_to_currency(self): "мiнус дванадцять тисяч п'ятсот дев'ятнадцять євро, 85 центiв" ) self.assertEqual( - num2words('38.4', lang='uk', to='currency', seperator=' и', + num2words('38.4', lang='uk', to='currency', separator=' и', cents=False, currency='EUR'), "тридцять вiсiм євро и 40 центiв" ) From eef5b03593f77b30fcedafdfd2fa86893f391f98 Mon Sep 17 00:00:00 2001 From: Alvaro <26382770+ohduran@users.noreply.github.com> Date: Tue, 12 Feb 2019 19:59:46 +0100 Subject: [PATCH 012/340] =?UTF-8?q?Updates=20accents=20on=20c=C3=A9ntimos?= =?UTF-8?q?=20in=20Spanish=20(#240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updates accents on céntimos in Spanish * Update test_es.py * Update test_es.py * fix tests * fix encoding * Update tox.ini * Update test_cli.py * Update test_cli.py * Update test_cli.py * Update lang_AR.py flake-8 compliant * Update test_cli.py flake8 compliant * Update test_cli.py * Update test_cli.py --- num2words/lang_AR.py | 18 ++++++------- num2words/lang_ES.py | 8 +++--- tests/test_cli.py | 5 ++-- tests/test_es.py | 62 ++++++++++++++++++++++---------------------- tox.ini | 4 +++ 5 files changed, 51 insertions(+), 46 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 843d7972..a0027a83 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -188,11 +188,11 @@ 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: + if ret_val != "" 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)] @@ -226,9 +226,9 @@ def convert_to_arabic(self): 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 "": + if ret_val != "": ret_val = "{} و {}".format("", ret_val) if number_to_process != 2: if number_to_process % 100 != 1: @@ -236,7 +236,7 @@ def convert_to_arabic(self): 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 +250,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,7 +288,7 @@ 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 @@ -299,10 +299,10 @@ def validate_number(self, number): 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: diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index b1aafa67..fca94911 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -22,10 +22,10 @@ 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': (('dolar', 'dólares'), ('centavo', 'centavos')), + 'PEN': (('sol', 'soles'), ('céntimo', 'céntimos')), } # //CHECK: Is this sufficient?? diff --git a/tests/test_cli.py b/tests/test_cli.py index 00fc50c6..678ed2a5 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -106,6 +106,7 @@ def test_cli_with_lang_to(self): 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_es.py b/tests/test_es.py index 3c576d1b..a49cfbf2 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -112,47 +112,47 @@ ) 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'), + (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, 'veintiun 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, 'un peseta con cero céntimos'), + (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, 'veintiun pesetas con cero céntimos'), + (81.25, 'ochenta y un pesetas con veinticinco céntimos'), + (350.90, 'trescientos 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'), + (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, 'veintiun 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, 'veintiun 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'), ) diff --git a/tox.ini b/tox.ini index 34ff065f..11c8f61b 100644 --- a/tox.ini +++ b/tox.ini @@ -26,3 +26,7 @@ deps = delegator.py commands = isort --check-only --recursive --diff num2words tests + +[testenv:py27] +setenv = + PYTHONIOENCODING = UTF-8 From 18194b52efd2a17d72cea54c6851539f555634d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Bregar?= Date: Fri, 29 Mar 2019 18:47:18 +0100 Subject: [PATCH 013/340] Multitude of corrections of Slovene language (#246) * Multitude of corrections of Slovene language * Indentation correction for flake8 * Added tests from https://github.com/gregopet/num2words by @gregopet and merged them with existing. * Flake8ing tests. * Sorted imports * Some more sorting... * Last time for sorting? --- num2words/__init__.py | 40 ++--------- num2words/lang_SL.py | 40 +++++++++-- tests/test_cli.py | 1 + tests/test_sl.py | 153 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 189 insertions(+), 45 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 6df724c0..6a0216f9 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,40 +17,12 @@ 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_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, + lang_ES, lang_ES_CO, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, + lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, + lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), diff --git a/num2words/lang_SL.py b/num2words/lang_SL.py index 5472a613..fb0e2876 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() @@ -36,7 +36,7 @@ def setup(self): 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 +57,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 +104,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/tests/test_cli.py b/tests/test_cli.py index 678ed2a5..d8ea56cf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -22,6 +22,7 @@ import unittest import delegator + import num2words 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") From a8697458130d044bd8a5c1b4930276471eb67f0c Mon Sep 17 00:00:00 2001 From: Sarah Beranek <4508867+sarahberanek@users.noreply.github.com> Date: Fri, 12 Apr 2019 01:07:44 +0200 Subject: [PATCH 014/340] Fixing currency functions for german and french. Adding Currency_Forms for DE, FR and NL. (#247) * Fix currency function for French. Adding Currency_Forms. * Fix currency function for German. Adding Currency_Forms. * Move FR_DZ to new currency functions, too. * Fix tests * Add more currency options for dutch. * Add more tests for German, Dutch and French currencies. --- num2words/lang_DE.py | 29 +++++++------ num2words/lang_FR.py | 21 ++++++---- num2words/lang_FR_DZ.py | 15 ++++--- num2words/lang_NL.py | 5 ++- tests/test_de.py | 90 ++++++++++++++++++++++++++++++----------- tests/test_fr.py | 59 +++++++++++++++++---------- tests/test_fr_be.py | 38 ++++++++--------- tests/test_fr_ch.py | 39 +++++++++--------- tests/test_fr_dz.py | 6 +-- tests/test_nl.py | 25 +++++++++++- 10 files changed, 212 insertions(+), 115 deletions(-) diff --git a/num2words/lang_DE.py b/num2words/lang_DE.py index 348b44f5..ad61b18e 100644 --- a/num2words/lang_DE.py +++ b/num2words/lang_DE.py @@ -23,6 +23,14 @@ 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" @@ -134,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_FR.py b/num2words/lang_FR.py index 85ef87ed..0c440b3f 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) @@ -92,10 +100,9 @@ def to_ordinal_num(self, value): 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_NL.py b/num2words/lang_NL.py index ec052d31..ac4d4051 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" diff --git a/tests/test_de.py b/tests/test_de.py index 2e50e5c3..119d3326 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -21,6 +21,46 @@ 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): @@ -93,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_fr.py b/tests/test_fr.py index 6170cb70..538be341 100644 --- a/tests/test_fr.py +++ b/tests/test_fr.py @@ -118,26 +118,34 @@ (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'), ) @@ -175,16 +183,23 @@ 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', currency='EUR'), + test[1] + ) + + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: self.assertEqual( - num2words(test[0], lang='fr', to='currency'), + num2words(test[0], lang='fr', to='currency', currency='FRF'), test[1] ) - def test_currency_old(self): - for test in TEST_CASES_TO_CURRENCY_OLD: + def test_currency_usd(self): + for test in TEST_CASES_TO_CURRENCY_USD: self.assertEqual( - num2words(test[0], lang='fr', to='currency', old=True), + num2words(test[0], lang='fr', to='currency', currency='USD'), test[1] ) 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_nl.py b/tests/test_nl.py index 52ae6781..e72b43bf 100644 --- a/tests/test_nl.py +++ b/tests/test_nl.py @@ -67,7 +67,7 @@ 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', separator=' en', cents=False, currency='EUR'), @@ -90,6 +90,29 @@ def test_to_currency(self): 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 From f4b2bac098ae8e4850cf2f185f6ff52a5979641f Mon Sep 17 00:00:00 2001 From: Chintalagiri Shashank Date: Fri, 12 Apr 2019 05:44:59 +0530 Subject: [PATCH 015/340] Add support for the Indian rupee. (#248) --- num2words/lang_EU.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 4a301af7..022d369b 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -42,6 +42,7 @@ class Num2Word_EU(Num2Word_Base): 'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')), 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei'), ('ban', 'bani')), + 'INR': (('rupee', 'rupees'), ('paisa', 'paise')) } CURRENCY_ADJECTIVES = { @@ -53,6 +54,7 @@ class Num2Word_EU(Num2Word_Base): 'NOK': 'Norwegian', 'MXN': 'Mexican', 'RON': 'Romanian', + 'INR': 'Indian', } GIGA_SUFFIX = "illiard" From f6dc5a3893fbe5872c3f71907459e4789c65caec Mon Sep 17 00:00:00 2001 From: Filippo Costa Date: Tue, 7 May 2019 17:04:19 +0200 Subject: [PATCH 016/340] Revert some copyright changes made in commit 53b4518 (#254) Commit 53b4518 made added explicit utf-8 encoding for all sources, among other things. A copyright notice in `tests/test_tr.py` was removed and two were added in `num2words/lang_it.py`. I know this was a simple mistake, I just thought it would be best to explicitly give credit where credit is due. --- num2words/lang_IT.py | 3 +-- tests/test_tr.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index f1eb0232..ce6645f9 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 diff --git a/tests/test_tr.py b/tests/test_tr.py index 02073e07..6622ddc6 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. From cbfc8fd5d0955ff34cef390deb3fbbea5c1b71e8 Mon Sep 17 00:00:00 2001 From: Akhilesh Date: Sun, 12 May 2019 20:33:31 +0530 Subject: [PATCH 017/340] add kannada language support (#243) * add kannada support * add Kannada Language support * add tests for kannada * reformatted * change lang param * fix tests * add condition * add modifier * add few more test cases * fix test * fix test * modify test * fix flake8 * fix isort * add more tests * add unicode prefix * edit tests for float numbers * add more tests * add unicode prefix in tests * add Kannada language --- README.rst | 1 + num2words/__init__.py | 9 ++- num2words/lang_KN.py | 182 ++++++++++++++++++++++++++++++++++++++++++ tests/test_kn.py | 67 ++++++++++++++++ 4 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 num2words/lang_KN.py create mode 100644 tests/test_kn.py diff --git a/README.rst b/README.rst index 8e509c15..6c7bcecf 100644 --- a/README.rst +++ b/README.rst @@ -95,6 +95,7 @@ Besides the numerical argument, there are two main optional arguments. * ``id`` (Indonesian) * ``it`` (Italian) * ``ja`` (Japanese) +* ``kn`` (Kannada) * ``ko`` (Korean) * ``lt`` (Lithuanian) * ``lv`` (Latvian) diff --git a/num2words/__init__.py b/num2words/__init__.py index 6a0216f9..b1a266ba 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -20,9 +20,9 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, - lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, - lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_TH, - lang_TR, lang_UK, lang_VI) + lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, + lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -40,6 +40,7 @@ '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(), 'lt': lang_LT.Num2Word_LT(), 'lv': lang_LV.Num2Word_LV(), @@ -73,8 +74,10 @@ 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) diff --git a/num2words/lang_KN.py b/num2words/lang_KN.py new file mode 100644 index 00000000..430c52f9 --- /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 .base import Num2Word_Base + + +class Num2Word_KN(Num2Word_Base): + 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/tests/test_kn.py b/tests/test_kn.py new file mode 100644 index 00000000..6be20547 --- /dev/null +++ b/tests/test_kn.py @@ -0,0 +1,67 @@ +# -*- 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'ಒಂದು ಸಾವಿರದ ಮೂರನೇ' + ) + + def test_ordinal_num(self): + 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"ಒಂದು ನೂರ ಹದಿಮೂರನೇ") From 2d1a318359834f133a566d0a56c7c23e71fba449 Mon Sep 17 00:00:00 2001 From: Ernesto Rodriguez Ortiz Date: Sun, 12 May 2019 11:18:24 -0400 Subject: [PATCH 018/340] Release v0.5.10 --- CHANGES.rst | 16 ++++++++++++++++ bin/num2words | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0cbd2500..298f9db9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,22 @@ Changelog ========= + +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 --------------------------- diff --git a/bin/num2words b/bin/num2words index 7c9d595f..068abf25 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.9" +__version__ = "0.5.10" __license__ = "LGPL" From e88753046274cdef54ab86012313ba20a217036f Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Tue, 21 May 2019 18:15:38 +0200 Subject: [PATCH 019/340] Telugu Language num2words file --- num2words/__init__.py | 5 ++-- num2words/lang_TE.py | 56 +++++++++++++++++++++++++++++++++++++++++++ tests/test_te.py | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 num2words/lang_TE.py create mode 100644 tests/test_te.py diff --git a/num2words/__init__.py b/num2words/__init__.py index b1a266ba..002b7bf2 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,7 +22,7 @@ lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_TH, lang_TR, lang_UK, lang_VI, lang_TE) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -59,7 +59,8 @@ '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() } diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py new file mode 100644 index 00000000..1bdbe48c --- /dev/null +++ b/num2words/lang_TE.py @@ -0,0 +1,56 @@ +from __future__ import unicode_literals + +from .base import Num2Word_Base + + +class Num2Word_TE(Num2Word_Base): + 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: + 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/tests/test_te.py b/tests/test_te.py new file mode 100644 index 00000000..d74c8273 --- /dev/null +++ b/tests/test_te.py @@ -0,0 +1,48 @@ +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsTETest(TestCase): + def test_numbers(self): + 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(3.14, lang="te"), u"మూడు బిందువు ఒకటి నాలుగు ") + self.assertEqual(num2words(1.61803, 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(12, lang='te', to='ordinal'), + u'పన్నెండవ' + ) + self.assertEqual( + num2words(130, lang='te', to='ordinal'), + u'ఒక వంద ముప్పయ్యవ ' + ) + self.assertEqual( + num2words(1003, lang='te', to='ordinal'), + u'ఒక వెయ్యి మూడవ' + ) + + def test_ordinal_num(self): + self.assertEqual(num2words(2, lang="te", ordinal=True), u"రెండవ") + self.assertEqual(num2words(5, lang="te", ordinal=True), u"అయిదవ ") + self.assertEqual(num2words(16, lang="te", ordinal=True), u"పదహారవ ") + self.assertEqual(num2words(113, lang="te", ordinal=True), + u"ఒక వంద పదమూడవ") From bdf651d1fa3b85da270a212229075c63cf6f25e0 Mon Sep 17 00:00:00 2001 From: Maria S Date: Sun, 9 Jun 2019 12:24:01 +0300 Subject: [PATCH 020/340] romanian-issues-259: rough implementation --- num2words/lang_RO.py | 40 +++++++++++++++++++++++++++------------- tests/test_ro.py | 9 +++++++++ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index d4693b86..d692626a 100644 --- a/num2words/lang_RO.py +++ b/num2words/lang_RO.py @@ -48,13 +48,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 +67,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 +106,30 @@ def to_ordinal_num(self, value): return "1-ul" return "al %s-lea" % (value) - def inflect(self, value, text): + 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 = "".join(text) + # mega inflections are with 'oa' inside, use suffixes + if side_effect > 1 and result.endswith(self.MEGA_SUFFIX): + result = result.replace(self.MEGA_SUFFIX, self.MEGA_SUFFIX_I) + return result def to_currency(self, val, longval=True, old=False): cents = int(round(val*100)) + # romanian currency has a particularity for numeral: one + self.gen_numwords[1] = "una" result = self.to_splitnum(cents, hightxt="leu/i", lowtxt="ban/i", divisor=100, jointxt="și", longval=longval) + self.gen_numwords[1] = "o" # revert numeral return result.replace( "unu leu", "un leu" - ).replace("unu ban", "un ban") + ).replace( + "unu ban", "un ban" + ) def to_year(self, val, suffix=None, longval=True): result = super(Num2Word_RO, self).to_year( diff --git a/tests/test_ro.py b/tests/test_ro.py index b5e6c516..16813041 100644 --- a/tests/test_ro.py +++ b/tests/test_ro.py @@ -135,6 +135,15 @@ def test_to_currency(self): u'patru mii șapte sute șaptezeci și opt lei' u' și treizeci și doi bani') + self.assertEqual( + num2words(1200, lang='ro', to='currency'), + u'una mie două sute lei') + + + self.assertEqual( + num2words(22000, lang='ro', to='currency'), + u'douăzeci și două mii lei') + def test_to_year(self): self.assertEqual(num2words(1989, lang='ro', to='year'), u'o mie nouă sute optzeci și nouă') From a192afec85e5cc6dd2dc213f87fe431fcce96a6c Mon Sep 17 00:00:00 2001 From: Maria S Date: Sun, 9 Jun 2019 12:43:01 +0300 Subject: [PATCH 021/340] romanian-issues-259: test new branch --- tests/test_ro.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/test_ro.py b/tests/test_ro.py index 16813041..e0e5be7d 100644 --- a/tests/test_ro.py +++ b/tests/test_ro.py @@ -120,29 +120,30 @@ def test_to_currency(self): num2words(38.4, lang='ro', to='currency'), u'treizeci și opt lei și patruzeci 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') - self.assertEqual( num2words(4778.32, lang='ro', to='currency'), u'patru mii șapte sute șaptezeci și opt lei' u' și treizeci și doi bani') - self.assertEqual( num2words(1200, lang='ro', to='currency'), u'una mie două sute lei') - - self.assertEqual( num2words(22000, lang='ro', to='currency'), u'douăzeci și două mii lei') + self.assertEqual( + num2words(80000, lang='ro', to='currency'), + u'optzeci mii lei') + self.assertEqual( + num2words(123456789, lang='ro', to='currency'), + u'una sută douăzeci și trei milioane patru sute ' + u'cincizeci și șase mii șapte sute optzeci și nouă lei') def test_to_year(self): self.assertEqual(num2words(1989, lang='ro', to='year'), From 6b3d3033321eb7bb845711e3b246474d1222d35d Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Thu, 13 Jun 2019 17:26:17 +0200 Subject: [PATCH 022/340] Add Telugu Num2Words. --- num2words/__init__.py | 2 +- num2words/lang_TE.py | 54 ++++++++++++++++++++++++++++++++----------- tests/test_te.py | 23 +++++++++++------- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 002b7bf2..57451022 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,7 +22,7 @@ lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, - lang_TH, lang_TR, lang_UK, lang_VI, lang_TE) + lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py index 1bdbe48c..819ebcdb 100644 --- a/num2words/lang_TE.py +++ b/num2words/lang_TE.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from __future__ import unicode_literals from .base import Num2Word_Base @@ -10,25 +12,51 @@ def set_high_numwords(self, high): def setup(self): self.low_numwords = [ - - "తొంభై తొమ్మిది", "తొంభై ఎనిమిది", "తొంభై ఏడు", "తొంభై ఆరు", "తొంభై అయిదు", "తొంభై నాలుగు ", "తొంభై మూడు", "తొంభై రెండు", "తొంభై ఒకటి", "తొంభై ", "ఎనభై తొమ్మిది", "ఎనభై ఎనిమిది", "ఎనభై ఏడు", "ఎనభై ఆరు", "ఎనభై అయిదు", - "ఎనభై నాలుగు", "ఎనభై మూడు", "ఎనభై రెండు" , "ఎనభై ఒకటి", "ఎనభై" ,"డెబ్బై తొమ్మిది" , "డెబ్బై ఎనిమిది" , "డెబ్బై ఏడు" , "డెబ్బై ఆరు" , "డెబ్బై అయిదు" , "డెబ్బై నాలుగు" ,"డెబ్బై మూడు", "డెబ్బై రెండు", "డెబ్బై ఒకటి" ,"డెబ్బై" , - "అరవై తొమ్మిది ", "అరవై ఎనిమిది" , "అరవై ఏడు " , "అరవై ఆరు ","అరవై అయిదు ", "అరవై నాలుగు ", "అరవై మూడు ", "అరవై రెండు ", "అరవై ఒకటి" , "అరవై " , "యాభై తొమ్మిది", "యాభై ఎనిమిది" , "యాభై ఏడు", "యాభై ఆరు", - "యాభై అయిదు", "యాభై నాలుగు", "యాభై మూడు" , "యాభై రెండు", "యాభై ఒకటి", "యాభై " , "నలభై తొమ్మిది" ,"నలభై ఎనిమిది", "నలభై ఏడు", "నలభై ఆరు", "నలభై అయిదు" , "నలభై నాలుగు", "నలభై మూడు", "నలభై రెండు" , - "నలభై ఒకటి" , "నలభై" , "ముప్పై తొమ్మిది", "ముప్పై ఎనిమిది", "ముప్పై ఏడు", "ముప్పై ఆరు", "ముప్పై ఐదు", "ముప్పై నాలుగు", "ముప్పై మూడు", "ముప్పై రెండు", "ముప్పై ఒకటి", "ముప్పై", "ఇరవై తొమ్మిది", "ఇరవై ఎనిమిది", "ఇరవై ఏడు", - "ఇరవై ఆరు", "ఇరవై అయిదు", "ఇరవై నాలుగు", "ఇరవై మూడు", "ఇరవై రెండు", "ఇరవై ఒకటి", "ఇరవై", "పందొమ్మిది", "పధ్ధెనిమిది", "పదిహేడు", "పదహారు", "పదునయిదు", "పధ్నాలుగు", "పదమూడు", "పన్నెండు", "పదకొండు", "పది", "తొమ్మిది", - "ఎనిమిది", "ఏడు", "ఆరు", "అయిదు","నాలుగు", "మూడు", "రెండు", "ఒకటి", "సున్న" - ] + "తొంభై తొమ్మిది", "తొంభై ఎనిమిది", "తొంభై ఏడు", "తొంభై ఆరు", + "తొంభై అయిదు", "తొంభై నాలుగు ", "తొంభై మూడు", "తొంభై రెండు", + "తొంభై ఒకటి", "తొంభై ", "ఎనభై తొమ్మిది", "ఎనభై ఎనిమిది", + "ఎనభై ఏడు", "ఎనభై ఆరు", "ఎనభై అయిదు", "ఎనభై నాలుగు", + "ఎనభై మూడు", "ఎనభై రెండు", "ఎనభై ఒకటి", "ఎనభై", + "డెబ్బై తొమ్మిది", "డెబ్బై ఎనిమిది", "డెబ్బై ఏడు", + "డెబ్బై ఆరు", "డెబ్బై అయిదు", "డెబ్బై నాలుగు", + "డెబ్బై మూడు", "డెబ్బై రెండు", + "డెబ్బై ఒకటి", "డెబ్బై", "అరవై తొమ్మిది ", "అరవై ఎనిమిది", + "అరవై ఏడు ", "అరవై ఆరు ", "అరవై అయిదు ", "అరవై నాలుగు ", + "అరవై మూడు ", "అరవై రెండు ", + "అరవై ఒకటి", "అరవై ", + "యాభై తొమ్మిది", "యాభై ఎనిమిది", + "యాభై ఏడు", "యాభై ఆరు", + "యాభై అయిదు", "యాభై నాలుగు", + "యాభై మూడు", "యాభై రెండు", + "యాభై ఒకటి", "యాభై ", + "నలభై తొమ్మిది", "నలభై ఎనిమిది", "నలభై ఏడు", + "నలభై ఆరు", "నలభై అయిదు", + "నలభై నాలుగు", "నలభై మూడు", "నలభై రెండు", + "నలభై ఒకటి", "నలభై", "ముప్పై తొమ్మిది", + "ముప్పై ఎనిమిది", "ముప్పై ఏడు", "ముప్పై ఆరు", "ముప్పై ఐదు", + "ముప్పై నాలుగు", "ముప్పై మూడు", + "ముప్పై రెండు", "ముప్పై ఒకటి", "ముప్పై", "ఇరవై తొమ్మిది", + "ఇరవై ఎనిమిది", "ఇరవై ఏడు", + "ఇరవై ఆరు", "ఇరవై అయిదు", "ఇరవై నాలుగు", + "ఇరవై మూడు", "ఇరవై రెండు", "ఇరవై ఒకటి", "ఇరవై", + "పందొమ్మిది", "పధ్ధెనిమిది", "పదిహేడు", "పదహారు", + "పదునయిదు", "పధ్నాలుగు", + "పదమూడు", "పన్నెండు", "పదకొండు", "పది", "తొమ్మిది", + "ఎనిమిది", "ఏడు", "ఆరు", "అయిదు", + "నాలుగు", "మూడు", "రెండు", "ఒకటి", "సున్న" + ] self.mid_numwords = [(100, "వందల")] - self.high_numwords = [(7, "కోటి" ), (5, "లక్షల"), (3, "వేల" )] + self.high_numwords = [(7, "కోటి"), (5, "లక్షల"), (3, "వేల")] self.pointword = "బిందువు " - self.modifiers = [ - " ్ ","ా", " ి ", " ీ "," ు "," ూ " ," ృ "," ౄ " ," ె " ," ే " ," ై " ," ొ" ," ో " ," ౌ " ," ఁ " ," ం " ," ః " - ] + self.modifiers = [ + " ్ ", "ా", " ి ", " ీ ", " ు ", " ూ ", " ృ ", + " ౄ ", " ె ", " ే ", " ై ", " ొ", " ో ", + " ౌ ", " ఁ ", " ం ", " ః " + ] def merge(self, lpair, rpair): ltext, lnum = lpair diff --git a/tests/test_te.py b/tests/test_te.py index d74c8273..fc806d5f 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from unittest import TestCase from num2words import num2words @@ -5,23 +7,26 @@ class Num2WordsTETest(TestCase): def test_numbers(self): - self.assertEqual(num2words(42, 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"ముప్పై రెండు వేల రెండు వందల పదకొండు") + u"ముప్పై రెండు వేల రెండు వందల పదకొండు") def test_cardinal_for_float_number(self): - self.assertEqual(num2words(3.14, lang="te"), u"మూడు బిందువు ఒకటి నాలుగు ") + self.assertEqual( + num2words(3.14, lang="te"), + u"మూడుబిందువు ఒకటి నాలుగు" + ) self.assertEqual(num2words(1.61803, lang="te"), u"ఒకటి బిందువు ఆరు ఒకటి ఎనిమిది సున్నా మూడు ") def test_ordinal(self): self.assertEqual( num2words(1, lang='te', to='ordinal'), - u'ఒకటవ ' + u'ఒకటివ ' ) self.assertEqual( num2words(22, lang='te', to='ordinal'), @@ -41,8 +46,10 @@ def test_ordinal(self): ) def test_ordinal_num(self): - self.assertEqual(num2words(2, lang="te", ordinal=True), u"రెండవ") + self.assertEqual( + num2words(2, lang="te", ordinal=True), u"రెండవ") self.assertEqual(num2words(5, lang="te", ordinal=True), u"అయిదవ ") - self.assertEqual(num2words(16, lang="te", ordinal=True), u"పదహారవ ") - self.assertEqual(num2words(113, lang="te", ordinal=True), - u"ఒక వంద పదమూడవ") + self.assertEqual( + num2words(16, lang="te", ordinal=True), u"పదహారవ ") + self.assertEqual( + num2words(113, lang="te", ordinal=True), u"ఒక వంద పదమూడవ") From a2900faccf4922cf6c0be863fe0ddb4292ec40b8 Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Thu, 4 Jul 2019 17:43:00 +0200 Subject: [PATCH 023/340] Final telugu num2words. --- num2words/lang_KN.py | 6 +- num2words/lang_TE.py | 160 ++++++++++++++++++++++++++++++++----------- tests/test_te.py | 75 ++++++++++---------- 3 files changed, 160 insertions(+), 81 deletions(-) diff --git a/num2words/lang_KN.py b/num2words/lang_KN.py index 430c52f9..3bc1ccae 100644 --- a/num2words/lang_KN.py +++ b/num2words/lang_KN.py @@ -17,13 +17,13 @@ from __future__ import unicode_literals -from .base import Num2Word_Base +from .lang_EU import Num2Word_EU -class Num2Word_KN(Num2Word_Base): +class Num2Word_KN(Num2Word_EU): def set_high_numwords(self, high): for n, word in self.high_numwords: - self.cards[10 ** n] = word + self.cards[10**n] = word def setup(self): self.low_numwords = [ diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py index 819ebcdb..54fb1fba 100644 --- a/num2words/lang_TE.py +++ b/num2words/lang_TE.py @@ -2,48 +2,116 @@ from __future__ import unicode_literals -from .base import Num2Word_Base +from .lang_EU import Num2Word_EU -class Num2Word_TE(Num2Word_Base): +class Num2Word_TE(Num2Word_EU): def set_high_numwords(self, high): for n, word in self.high_numwords: - self.cards[10 ** n] = word + self.cards[10**n] = word def setup(self): self.low_numwords = [ - "తొంభై తొమ్మిది", "తొంభై ఎనిమిది", "తొంభై ఏడు", "తొంభై ఆరు", - "తొంభై అయిదు", "తొంభై నాలుగు ", "తొంభై మూడు", "తొంభై రెండు", - "తొంభై ఒకటి", "తొంభై ", "ఎనభై తొమ్మిది", "ఎనభై ఎనిమిది", - "ఎనభై ఏడు", "ఎనభై ఆరు", "ఎనభై అయిదు", "ఎనభై నాలుగు", - "ఎనభై మూడు", "ఎనభై రెండు", "ఎనభై ఒకటి", "ఎనభై", - "డెబ్బై తొమ్మిది", "డెబ్బై ఎనిమిది", "డెబ్బై ఏడు", - "డెబ్బై ఆరు", "డెబ్బై అయిదు", "డెబ్బై నాలుగు", - "డెబ్బై మూడు", "డెబ్బై రెండు", - "డెబ్బై ఒకటి", "డెబ్బై", "అరవై తొమ్మిది ", "అరవై ఎనిమిది", - "అరవై ఏడు ", "అరవై ఆరు ", "అరవై అయిదు ", "అరవై నాలుగు ", - "అరవై మూడు ", "అరవై రెండు ", - "అరవై ఒకటి", "అరవై ", - "యాభై తొమ్మిది", "యాభై ఎనిమిది", - "యాభై ఏడు", "యాభై ఆరు", - "యాభై అయిదు", "యాభై నాలుగు", - "యాభై మూడు", "యాభై రెండు", - "యాభై ఒకటి", "యాభై ", - "నలభై తొమ్మిది", "నలభై ఎనిమిది", "నలభై ఏడు", - "నలభై ఆరు", "నలభై అయిదు", - "నలభై నాలుగు", "నలభై మూడు", "నలభై రెండు", - "నలభై ఒకటి", "నలభై", "ముప్పై తొమ్మిది", - "ముప్పై ఎనిమిది", "ముప్పై ఏడు", "ముప్పై ఆరు", "ముప్పై ఐదు", - "ముప్పై నాలుగు", "ముప్పై మూడు", - "ముప్పై రెండు", "ముప్పై ఒకటి", "ముప్పై", "ఇరవై తొమ్మిది", - "ఇరవై ఎనిమిది", "ఇరవై ఏడు", - "ఇరవై ఆరు", "ఇరవై అయిదు", "ఇరవై నాలుగు", - "ఇరవై మూడు", "ఇరవై రెండు", "ఇరవై ఒకటి", "ఇరవై", - "పందొమ్మిది", "పధ్ధెనిమిది", "పదిహేడు", "పదహారు", - "పదునయిదు", "పధ్నాలుగు", - "పదమూడు", "పన్నెండు", "పదకొండు", "పది", "తొమ్మిది", - "ఎనిమిది", "ఏడు", "ఆరు", "అయిదు", - "నాలుగు", "మూడు", "రెండు", "ఒకటి", "సున్న" + "తొంభై తొమ్మిది", + "తొంభై ఎనిమిది", + "తొంభై ఏడు", + "తొంభై ఆరు", + "తొంభై అయిదు", + "తొంభై నాలుగు", + "తొంభై మూడు", + "తొంభై రెండు", + "తొంభై ఒకటి", + "తొంభై", + "ఎనభై తొమ్మిది", + "ఎనభై ఎనిమిది", + "ఎనభై ఏడు", + "ఎనభై ఆరు", + "ఎనభై అయిదు", + "ఎనభై నాలుగు", + "ఎనభై మూడు", + "ఎనభై రెండు", + "ఎనభై ఒకటి", + "ఎనభై", + "డెబ్బై తొమ్మిది", + "డెబ్బై ఎనిమిది", + "డెబ్బై ఏడు", + "డెబ్బై ఆరు", + "డెబ్బై అయిదు", + "డెబ్బై నాలుగు", + "డెబ్బై మూడు", + "డెబ్బై రెండు", + "డెబ్బై ఒకటి", + "డెబ్బై", + "అరవై తొమ్మిది", + "అరవై ఎనిమిది", + "అరవై ఏడు", + "అరవై ఆరు", + "అరవై అయిదు", + "అరవై నాలుగు", + "అరవై మూడు", + "అరవై రెండు", + "అరవై ఒకటి", + "అరవై", + "యాభై తొమ్మిది", + "యాభై ఎనిమిది", + "యాభై ఏడు", + "యాభై ఆరు", + "యాభై అయిదు", + "యాభై నాలుగు", + "యాభై మూడు", + "యాభై రెండు", + "యాభై ఒకటి", + "యాభై ", + "నలభై తొమ్మిది", + "నలభై ఎనిమిది", + "నలభై ఏడు", + "నలభై ఆరు", + "నలభై అయిదు", + "నలభై నాలుగు", + "నలభై మూడు", + "నలభై రెండు", + "నలభై ఒకటి", + "నలభై", + "ముప్పై తొమ్మిది", + "ముప్పై ఎనిమిది", + "ముప్పై ఏడు", + "ముప్పై ఆరు", + "ముప్పై ఐదు", + "ముప్పై నాలుగు", + "ముప్పై మూడు", + "ముప్పై రెండు", + "ముప్పై ఒకటి", + "ముప్పై", + "ఇరవై తొమ్మిది", + "ఇరవై ఎనిమిది", + "ఇరవై ఏడు", + "ఇరవై ఆరు", + "ఇరవై అయిదు", + "ఇరవై నాలుగు", + "ఇరవై మూడు", + "ఇరవై రెండు", + "ఇరవై ఒకటి", + "ఇరవై", + "పందొమ్మిది", + "పధ్ధెనిమిది", + "పదిహేడు", + "పదహారు", + "పదునయిదు", + "పధ్నాలుగు", + "పదమూడు", + "పన్నెండు", + "పదకొండు", + "పది", + "తొమ్మిది", + "ఎనిమిది", + "ఏడు", + "ఆరు", + "అయిదు", + "నాలుగు", + "మూడు", + "రెండు", + "ఒకటి", + "సున్న", ] self.mid_numwords = [(100, "వందల")] @@ -53,9 +121,23 @@ def setup(self): self.pointword = "బిందువు " self.modifiers = [ - " ్ ", "ా", " ి ", " ీ ", " ు ", " ూ ", " ృ ", - " ౄ ", " ె ", " ే ", " ై ", " ొ", " ో ", - " ౌ ", " ఁ ", " ం ", " ః " + " ్ ", + "ా ", + " ి ", + " ీ ", + " ు ", + " ూ ", + " ృ ", + " ౄ ", + " ె ", + " ే ", + " ై ", + " ొ", + " ో ", + " ౌ ", + " ఁ ", + " ం ", + " ః ", ] def merge(self, lpair, rpair): @@ -80,5 +162,5 @@ def to_ordinal(self, value): outwords = self.to_cardinal(value) if outwords[-1] in self.modifiers: outwords = outwords[:-1] - ordinal_num = outwords + "వ " + ordinal_num = outwords + "వ" return ordinal_num diff --git a/tests/test_te.py b/tests/test_te.py index fc806d5f..bd804b1c 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -1,4 +1,19 @@ # -*- 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 @@ -7,49 +22,31 @@ class Num2WordsTETest(TestCase): def test_numbers(self): - 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"ముప్పై రెండు వేల రెండు వందల పదకొండు") + 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"యాభై నాలుగు వేల నాలుగు వందల పదకొండు") def test_cardinal_for_float_number(self): - self.assertEqual( - num2words(3.14, lang="te"), - u"మూడుబిందువు ఒకటి నాలుగు" - ) self.assertEqual(num2words(1.61803, lang="te"), - u"ఒకటి బిందువు ఆరు ఒకటి ఎనిమిది సున్నా మూడు ") + 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(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(1, 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"ఒకటి వేల మూడువ") def test_ordinal_num(self): - self.assertEqual( - num2words(2, lang="te", ordinal=True), u"రెండవ") - self.assertEqual(num2words(5, lang="te", ordinal=True), u"అయిదవ ") - self.assertEqual( - num2words(16, lang="te", ordinal=True), u"పదహారవ ") - self.assertEqual( - num2words(113, lang="te", ordinal=True), u"ఒక వంద పదమూడవ") + self.assertEqual(num2words(3, lang="te", ordinal=True), u"మూడువ") + self.assertEqual(num2words(5, lang="te", ordinal=True), u"అయిదువ") + self.assertEqual(num2words(16, lang="te", ordinal=True), u"పదహారువ") + self.assertEqual(num2words(113, lang="te", ordinal=True), + u"ఒకటి వందల పదమూడువ") From 607e270cadf1b41368678fbe4dc3c11eab8ba44b Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Wed, 17 Jul 2019 10:59:07 +0200 Subject: [PATCH 024/340] correction for telugu test case --- tests/test_te.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_te.py b/tests/test_te.py index bd804b1c..620209e2 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -33,6 +33,9 @@ def test_numbers(self): def test_cardinal_for_float_number(self): self.assertEqual(num2words(1.61803, lang="te"), u"ఒకటి బిందువు ఆరు ఒకటి ఎనిమిది సున్న మూడు") + + self.assertEqual(num2words(34.876, lang="te"), + u"ముప్పై నాలుగు బిందువు ఎనిమిది ఏడు ఆరు") def test_ordinal(self): self.assertEqual(num2words(1, lang='te', to='ordinal'), u"ఒకటివ") From 02830125325a05c4a4c204369b61724a9cf0158a Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Wed, 17 Jul 2019 11:50:25 +0200 Subject: [PATCH 025/340] 2nd correction for telugu test case and lang_TE --- num2words/lang_TE.py | 9 ++++++--- tests/test_te.py | 7 +++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py index 54fb1fba..49d8149a 100644 --- a/num2words/lang_TE.py +++ b/num2words/lang_TE.py @@ -114,9 +114,9 @@ def setup(self): "సున్న", ] - self.mid_numwords = [(100, "వందల")] + self.mid_numwords = [(100, "వంద")] - self.high_numwords = [(7, "కోటి"), (5, "లక్షల"), (3, "వేల")] + self.high_numwords = [(7, "కోటి"), (5, "లక్ష"), (3, "వేయి")] self.pointword = "బిందువు " @@ -148,7 +148,10 @@ def merge(self, lpair, rpair): elif 100 > lnum > rnum: return ("%s-%s" % (ltext, rtext), lnum + rnum) elif lnum >= 100 > rnum: - return ("%s %s" % (ltext, rtext), lnum + 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) diff --git a/tests/test_te.py b/tests/test_te.py index 620209e2..02a1ab9d 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -24,16 +24,15 @@ class Num2WordsTETest(TestCase): def test_numbers(self): self.assertEqual(num2words(66, lang="te"), u"అరవై ఆరు") self.assertEqual(num2words(1734, lang="te"), - u"ఒకటి వేల ఏడు వందల ముప్పై నాలుగు") + u"ఒకటి వేయి ఏడు వందల ముప్పై నాలుగు") self.assertEqual(num2words(134, lang="te"), u"ఒకటి వందల ముప్పై నాలుగు") self.assertEqual(num2words(54411, lang="te"), - u"యాభై నాలుగు వేల నాలుగు వందల పదకొండు") + u"యాభై నాలుగు వేయి నాలుగు వందల పదకొండు") def test_cardinal_for_float_number(self): self.assertEqual(num2words(1.61803, lang="te"), u"ఒకటి బిందువు ఆరు ఒకటి ఎనిమిది సున్న మూడు") - self.assertEqual(num2words(34.876, lang="te"), u"ముప్పై నాలుగు బిందువు ఎనిమిది ఏడు ఆరు") @@ -45,7 +44,7 @@ def test_ordinal(self): self.assertEqual(num2words(130, lang='te', to='ordinal'), u"ఒకటి వందల ముప్పైవ") self.assertEqual(num2words(1003, lang='te', to='ordinal'), - u"ఒకటి వేల మూడువ") + u"ఒకటి వేయిల మూడువ") def test_ordinal_num(self): self.assertEqual(num2words(3, lang="te", ordinal=True), u"మూడువ") From 3c51be6c1f5a9ab2f3501a836e2d5676c041b068 Mon Sep 17 00:00:00 2001 From: VENUGOPAL ACHHE Date: Mon, 22 Jul 2019 09:36:57 +0200 Subject: [PATCH 026/340] correction for ordinal case telugu test case and lang_TE --- num2words/lang_TE.py | 6 +++--- tests/test_te.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py index 49d8149a..274d3125 100644 --- a/num2words/lang_TE.py +++ b/num2words/lang_TE.py @@ -116,7 +116,7 @@ def setup(self): self.mid_numwords = [(100, "వంద")] - self.high_numwords = [(7, "కోటి"), (5, "లక్ష"), (3, "వేయి")] + self.high_numwords = [(7, "కోట్ల"), (5, "లక్ష"), (3, "వేయి")] self.pointword = "బిందువు " @@ -151,14 +151,14 @@ def merge(self, lpair, rpair): if ltext[-1] in self.modifiers: return ("%s %s" % (ltext[:-1], rtext), lnum + rnum) else: - return ("%s %s" % (ltext + "ల", rtext), lnum + rnum) + return ("%s %s" % (ltext+"ల", rtext), lnum + rnum) elif rnum > lnum: return ("%s %s" % (ltext, rtext), lnum * rnum) return ("%s %s" % (ltext, rtext), lnum + rnum) def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)) + return "%s%s" % (value, self.to_ordinal(value)[-1:]) def to_ordinal(self, value): self.verify_ordinal(value) diff --git a/tests/test_te.py b/tests/test_te.py index 02a1ab9d..bd3f4016 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -47,8 +47,8 @@ def test_ordinal(self): u"ఒకటి వేయిల మూడువ") def test_ordinal_num(self): - self.assertEqual(num2words(3, lang="te", ordinal=True), u"మూడువ") - self.assertEqual(num2words(5, lang="te", ordinal=True), u"అయిదువ") - self.assertEqual(num2words(16, lang="te", ordinal=True), u"పదహారువ") - self.assertEqual(num2words(113, lang="te", ordinal=True), - u"ఒకటి వందల పదమూడువ") + 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వ") From b89acf67090ff827273af108d14c2f14f0c6c964 Mon Sep 17 00:00:00 2001 From: Sarah Beranek Date: Mon, 19 Aug 2019 12:19:33 +0200 Subject: [PATCH 027/340] Add Ordinal Numbers Test for Kannada. --- tests/test_kn.py | 10 ++++++++-- tests/test_te.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/test_kn.py b/tests/test_kn.py index 6be20547..fa42cbd3 100644 --- a/tests/test_kn.py +++ b/tests/test_kn.py @@ -58,10 +58,16 @@ def test_ordinal(self): num2words(1003, lang='kn', to='ordinal'), u'ಒಂದು ಸಾವಿರದ ಮೂರನೇ' ) - - def test_ordinal_num(self): 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_te.py b/tests/test_te.py index bd3f4016..63143109 100644 --- a/tests/test_te.py +++ b/tests/test_te.py @@ -29,15 +29,28 @@ def test_numbers(self): 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"పన్నెండువ") @@ -45,8 +58,11 @@ def test_ordinal(self): 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వ") From d14f3388fff462e0fd0a1135df194fa82f80b388 Mon Sep 17 00:00:00 2001 From: Paola Coccia Date: Mon, 26 Aug 2019 18:07:30 +0200 Subject: [PATCH 028/340] Fixed misspelling of 21st (ordinal number) in IT language --- num2words/lang_IT.py | 1 + tests/test_it.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index ce6645f9..6966d730 100644 --- a/num2words/lang_IT.py +++ b/num2words/lang_IT.py @@ -52,6 +52,7 @@ def phonetic_contraction(string): .replace("ao", "o") # ex. "settantaotto" .replace("io", "o") # ex. "ventiotto" .replace("au", "u") # ex. "trentauno" + .replace("iu", "u") # ex. "ventiunesimo" ) diff --git a/tests/test_it.py b/tests/test_it.py index 23c79ce3..348f4ed8 100644 --- a/tests/test_it.py +++ b/tests/test_it.py @@ -78,6 +78,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 +155,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 +176,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" ) From ca5989a3ec9d7f13abbbc51f192afe8909f51422 Mon Sep 17 00:00:00 2001 From: Ivan Petukhov Date: Thu, 18 Jul 2019 11:15:29 +0300 Subject: [PATCH 029/340] Add KZT and UAH currencies to lang RU --- num2words/lang_RU.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 3b025268..e822d381 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -107,6 +107,12 @@ class Num2Word_RU(Num2Word_Base): 'USD': ( ('доллар', 'доллара', 'долларов'), ('цент', 'цента', 'центов') ), + 'UAH': ( + ('гривна', 'гривны', 'гривен'), ('копейка', 'копейки', 'копеек') + ), + 'KZT': ( + ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') + ), } def setup(self): From 5e15702912616b67746ce159e7b59bfe3231a3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Sat, 12 Oct 2019 18:12:13 -0600 Subject: [PATCH 030/340] Add es_NI currency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Examples: python bin/num2words 1 -l es_NI --to currency un córdoba con cero centavos python bin/num2words 1.02 -l es_NI --to currency un córdoba con dos centavos python bin/num2words 2.02 -l es_NI --to currency dos córdobas con dos centavos python bin/num2words 1.01 -l es_NI --to currency un córdoba con un centavo Signed-off-by: William José Moreno Reyes --- num2words/__init__.py | 3 ++- num2words/lang_ES_NI.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_ES_NI.py diff --git a/num2words/__init__.py b/num2words/__init__.py index b1a266ba..f03cc6b7 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, @@ -37,6 +37,7 @@ 'fi': lang_FI.Num2Word_FI(), 'es': lang_ES.Num2Word_ES(), 'es_CO': lang_ES_CO.Num2Word_ES_CO(), + '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(), 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") From 3202476d55677c90e3f638105fee3ab4ae705a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Sat, 19 Oct 2019 15:33:55 -0600 Subject: [PATCH 031/340] Add es_NI test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: William José Moreno Reyes --- num2words/__init__.py | 10 +++++----- tests/test_es_ni.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 tests/test_es_ni.py diff --git a/num2words/__init__.py b/num2words/__init__.py index f03cc6b7..07ef2bcd 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,11 +18,11 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, - lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_JA, - lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, - lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, + lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, + lang_JA, lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, + lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, + lang_SR, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), 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] + ) From 3cb0b40fd575bb8fdf5b2c7f1fad5d3a073b1399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Sat, 19 Oct 2019 16:27:50 -0600 Subject: [PATCH 032/340] =?UTF-8?q?Signed-off-by:=20William=20Jos=C3=A9=20?= =?UTF-8?q?Moreno=20Reyes=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test to check correct error raises This is a simple test to check that NotImplementedError raises fine. This also should improve test code coverage. --- tests/test_errors.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/test_errors.py diff --git a/tests/test_errors.py b/tests/test_errors.py new file mode 100644 index 00000000..fedc16ee --- /dev/null +++ b/tests/test_errors.py @@ -0,0 +1,29 @@ +# -*- 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") From 4f116228b585c331e23aee2f5427df6ce9230a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Sat, 19 Oct 2019 15:52:11 -0600 Subject: [PATCH 033/340] Update .gitignore to add .eggs/ directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: William José Moreno Reyes --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5e0679e9..e5a9b78d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ dist .idea/ *.egg-info /.tox +.eggs/ From 601e8cee848ee1ba382827a9d59853519383d7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Fri, 25 Oct 2019 19:38:55 -0600 Subject: [PATCH 034/340] Add AttributeError to to_cardinal_float MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: William José Moreno Reyes --- num2words/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/base.py b/num2words/base.py index 025e0145..ccf52482 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -139,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)) From e90061af65379b4bd4700abbed1dd40b2c4e9005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Fri, 25 Oct 2019 17:44:57 -0600 Subject: [PATCH 035/340] Add more tests to cover num2words/base.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: - https://github.com/savoirfairelinux/num2words/issues/125 Signed-off-by: William José Moreno Reyes --- tests/test_base.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index ea7701c8..d043066f 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -32,3 +32,29 @@ 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 + with self.assertRaises(TypeError): + Num2Word_Base.to_cardinal_float(9) + with self.assertRaises(TypeError): + Num2Word_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(9), + 9 + ) + self.base.is_title = True + self.assertEqual( + self.base.title("ii"), + "Ii" + ) From a1d29fc2bcb6d5878db997c31bc7ef00aff3d879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Jos=C3=A9=20Moreno=20Reyes?= Date: Fri, 25 Oct 2019 20:52:30 -0600 Subject: [PATCH 036/340] Update to title test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: William José Moreno Reyes --- tests/test_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_base.py b/tests/test_base.py index d043066f..bd9cbd13 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -50,11 +50,11 @@ def test_is_title(self): from num2words.base import Num2Word_Base self.base = Num2Word_Base() self.assertEqual( - self.base.title(9), - 9 + self.base.title("one"), + "one" ) self.base.is_title = True self.assertEqual( - self.base.title("ii"), - "Ii" + self.base.title("one"), + "One" ) From 7cd31a93f13a49a26cb4ab44173ec38d0218456f Mon Sep 17 00:00:00 2001 From: btharper Date: Sat, 26 Oct 2019 16:37:22 -0400 Subject: [PATCH 037/340] Add simple tests for lang_DK.py --- tests/test_dk.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/test_dk.py 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") From d82f739bc9cb87f9c5e79facba86a26b83c29266 Mon Sep 17 00:00:00 2001 From: btharper Date: Sat, 26 Oct 2019 17:37:47 -0400 Subject: [PATCH 038/340] Add ordinal 12,345 to ES test suite to increase coverage --- tests/test_es.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_es.py b/tests/test_es.py index a49cfbf2..7e99cfc4 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -95,6 +95,7 @@ (28, 'vigésimo octavo'), (100, 'centésimo'), (1000, 'milésimo'), + (12345, 'doce mil trescientos cuarenta y cinco'), (1000000, 'millonésimo'), (1000000000000000, 'cuadrillonésimo'), (1000000000000000000, 'un trillón') # over 1e18 is not supported From 6819f5a6ed4dce1b148b231c423bc827b6f1c3f4 Mon Sep 17 00:00:00 2001 From: btharper Date: Sat, 26 Oct 2019 22:38:50 -0400 Subject: [PATCH 039/340] Fix py2/3 difference on division and update test case --- num2words/lang_ES.py | 16 ++++++++++++---- tests/test_es.py | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index fca94911..7d6e46bf 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -17,6 +17,8 @@ from __future__ import print_function, unicode_literals +import math + from .lang_EU import Num2Word_EU @@ -143,25 +145,31 @@ def to_ordinal(self, value): 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 = 10 ** ((((len(str(int(value))) - 1) / 3 - 1) + 1) * 3) - part = int(float(value / dec) * dec) + 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(part / dec) if part / dec != 1 else "" + 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(value - part)) + self.to_ordinal(low_part)) ) else: text = self.to_cardinal(value) except KeyError: text = self.to_cardinal(value) + raise return text.strip() def to_ordinal_num(self, value): diff --git a/tests/test_es.py b/tests/test_es.py index 7e99cfc4..d306981b 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -95,7 +95,7 @@ (28, 'vigésimo octavo'), (100, 'centésimo'), (1000, 'milésimo'), - (12345, 'doce mil trescientos cuarenta y cinco'), + (12345, 'docemilésimo tricentésimo quadragésimo quinto'), (1000000, 'millonésimo'), (1000000000000000, 'cuadrillonésimo'), (1000000000000000000, 'un trillón') # over 1e18 is not supported From d161b4348d0545b3745929102c65fd12a41f082a Mon Sep 17 00:00:00 2001 From: btharper Date: Sat, 26 Oct 2019 23:22:23 -0400 Subject: [PATCH 040/340] Remove excess try/except KeyError block --- num2words/lang_ES.py | 88 +++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 7d6e46bf..a8cc47de 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -15,7 +15,7 @@ # 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 @@ -122,54 +122,48 @@ 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: - # 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 "" + 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)) ) - text = ( - "%s%s%s %s" % (cardinal, self.ords[dec], self.gender_stem, - self.to_ordinal(low_part)) - ) - else: - text = self.to_cardinal(value) - except KeyError: + 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: + # 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) - raise return text.strip() def to_ordinal_num(self, value): From b82bf457d452fb3918e11e9a7f421cce2996ba8b Mon Sep 17 00:00:00 2001 From: btharper Date: Sat, 26 Oct 2019 23:39:24 -0400 Subject: [PATCH 041/340] Fill out coverage for lang_EN.py --- tests/test_en.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_en.py b/tests/test_en.py index 15080877..6234ac98 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' From 28c304c2f489235b7bb56bdf67de075269fa740c Mon Sep 17 00:00:00 2001 From: Ariel Allon Date: Sun, 27 Oct 2019 23:46:02 -0500 Subject: [PATCH 042/340] Fix Hebrew support - Correct gender of 1 and 2 (and 11 and 12) to match remainder of numbers - Fix spelling of 8 (and 18 and 80) - Add cases for thousands 3-9 and support in the logic - Fix placement of "and" conjunction to match Academy of Hebrew Language position - Add tests --- num2words/lang_HE.py | 39 ++++++++++++++--------- tests/test_cli.py | 2 +- tests/test_he.py | 73 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 tests/test_he.py diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index c1d71a3c..0da469f6 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -18,32 +18,33 @@ from __future__ import print_function, unicode_literals +from .base import Num2Word_Base from .utils import get_digits, splitbyx ZERO = (u'אפס',) ONES = { - 1: (u'אחד',), - 2: (u'שנים',), + 1: (u'אחת',), + 2: (u'שתים',), 3: (u'שלש',), 4: (u'ארבע',), 5: (u'חמש',), 6: (u'שש',), 7: (u'שבע',), - 8: (u'שמנה',), + 8: (u'שמונה',), 9: (u'תשע',), } TENS = { 0: (u'עשר',), - 1: (u'אחד עשרה',), - 2: (u'שנים עשרה',), + 1: (u'אחת עשרה',), + 2: (u'שתים עשרה',), 3: (u'שלש עשרה',), 4: (u'ארבע עשרה',), 5: (u'חמש עשרה',), 6: (u'שש עשרה',), 7: (u'שבע עשרה',), - 8: (u'שמנה עשרה',), + 8: (u'שמונה עשרה',), 9: (u'תשע עשרה',), } @@ -54,7 +55,7 @@ 5: (u'חמישים',), 6: (u'ששים',), 7: (u'שבעים',), - 8: (u'שמנים',), + 8: (u'שמונים',), 9: (u'תשעים',), } @@ -67,6 +68,13 @@ THOUSANDS = { 1: (u'אלף',), 2: (u'אלפיים',), + 3: (u'שלשת אלפים',), + 4: (u'ארבעת אלפים',), + 5: (u'חמשת אלפים',), + 6: (u'ששת אלפים',), + 7: (u'שבעת אלפים',), + 8: (u'שמונת אלפים',), + 9: (u'תשעת אלפים',), } AND = u'ו' @@ -100,12 +108,15 @@ def int2word(n): n1, n2, n3 = get_digits(x) + if i > 0: + words.append(THOUSANDS[n1][0]) + continue + if n3 > 0: if n3 <= 2: words.append(HUNDRED[n3][0]) else: - words.append(ONES[n3][0]) - words.append(HUNDRED[3][0]) + words.append(ONES[n3][0] + ' ' + HUNDRED[3][0]) if n2 > 1: words.append(TWENTIES[n2][0]) @@ -116,14 +127,12 @@ def int2word(n): words.append(ONES[n1][0]) if i > 0: - if i <= 2: - words.append(THOUSANDS[i][0]) - else: - words.append(ONES[i][0]) - words.append(THOUSANDS[1][0]) + words.append(THOUSANDS[i][0]) + # source: 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/ if len(words) > 1: words[-1] = AND + words[-1] + return ' '.join(words) @@ -135,7 +144,7 @@ def to_currency(n, currency='EUR', cents=True, separator=','): raise NotImplementedError() -class Num2Word_HE(object): +class Num2Word_HE(Num2Word_Base): def to_cardinal(self, number): return n2w(number) diff --git a/tests/test_cli.py b/tests/test_cli.py index d8ea56cf..a85b1250 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -102,7 +102,7 @@ def test_cli_with_lang(self): ) 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) diff --git a/tests/test_he.py b/tests/test_he.py new file mode 100644 index 00000000..206d7cc5 --- /dev/null +++ b/tests/test_he.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 __future__ import unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsHETest(TestCase): + maxDiff = None + + 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'עשר') + + def test_11_to_19(self): + self.assertEqual(num2words(11, lang="he"), u'אחת עשרה') + self.assertEqual(num2words(13, lang="he"), u'שלש עשרה') + self.assertEqual(num2words(15, lang="he"), u'חמש עשרה') + self.assertEqual(num2words(16, lang="he"), 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(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(111, lang="he"), u'מאה ואחת עשרה') + self.assertEqual(num2words(150, lang="he"), u'מאה וחמישים') + self.assertEqual(num2words(196, lang="he"), u'מאה תשעים ושש') + self.assertEqual(num2words(200, lang="he"), 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(1001, lang="he"), u'אלף ואחת') + self.assertEqual(num2words(1500, lang="he"), u'אלף וחמש מאות') + self.assertEqual( + num2words(7378, lang="he"), u'שבעת אלפים שלש מאות שבעים ושמונה' + ) + self.assertEqual(num2words(2000, lang="he"), u'אלפיים') + self.assertEqual(num2words(2100, lang="he"), u'אלפיים ומאה') + self.assertEqual( + num2words(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים' + ) From c1e3e854bbf794d5734c9b2693ba3e12f6b5e811 Mon Sep 17 00:00:00 2001 From: Ariel Allon Date: Mon, 28 Oct 2019 00:01:21 -0500 Subject: [PATCH 043/340] Use non-url-encoded source URL to avoid CI rejection for too-long line --- num2words/lang_HE.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 0da469f6..34b2ec8a 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -129,7 +129,7 @@ def int2word(n): if i > 0: words.append(THOUSANDS[i][0]) - # source: 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/ + # source: https://hebrew-academy.org.il/2017/01/30/ו-החיבור-במספרים/ if len(words) > 1: words[-1] = AND + words[-1] From b362b7b347a5c2b162d1229410196c2d17ef0d59 Mon Sep 17 00:00:00 2001 From: mariaS210 Date: Thu, 7 Nov 2019 23:02:41 +0200 Subject: [PATCH 044/340] romanian-issues-259: implement and use pluralize --- num2words/lang_EU.py | 2 +- num2words/lang_RO.py | 44 +++++++++++++++++++++++++++++++++----------- tests/test_ro.py | 30 +++++++++++++++++++----------- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 022d369b..748f9356 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -41,7 +41,7 @@ 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')) } diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index d692626a..31a39508 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() @@ -106,29 +107,50 @@ def to_ordinal_num(self, value): return "1-ul" return "al %s-lea" % (value) + 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] - result = "".join(text) - # mega inflections are with 'oa' inside, use suffixes + 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)) + 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 = self.to_splitnum(cents, hightxt="leu/i", lowtxt="ban/i", - divisor=100, jointxt="și", longval=longval) + 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( + # if the romanian low text is 0, it is not usually printed + separator + " zero bani", "" ) def to_year(self, val, suffix=None, longval=True): diff --git a/tests/test_ro.py b/tests/test_ro.py index e0e5be7d..007316f8 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,9 +116,17 @@ 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(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'), @@ -126,24 +134,24 @@ def test_to_currency(self): ) 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(1200, lang='ro', to='currency'), - u'una mie două sute lei') + 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ă mii lei') + u'douăzeci și două de mii de lei') self.assertEqual( - num2words(80000, lang='ro', to='currency'), - u'optzeci mii lei') + num2words(13000, lang='ro', to='currency'), + u'treisprezece 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 mii șapte sute optzeci și nouă lei') + 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'), From 09d5da35559c65c39f7103bb48d05bfde39c6e3d Mon Sep 17 00:00:00 2001 From: mariaS210 Date: Thu, 7 Nov 2019 23:08:16 +0200 Subject: [PATCH 045/340] romanian-issues-259: fix linter error --- num2words/lang_RO.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index 31a39508..ec1deda3 100644 --- a/num2words/lang_RO.py +++ b/num2words/lang_RO.py @@ -133,7 +133,8 @@ def inflect(self, value, text, side_effect=-1): result = result.replace("iliare", self.GIGA_SUFFIX_I) return result - def to_currency(self, val, currency="RON", cents=False, separator=" și", adjective=False): + 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( From dc7f7907e55566684dec32c4a26608078092a2c0 Mon Sep 17 00:00:00 2001 From: mariaS210 Date: Thu, 7 Nov 2019 23:29:43 +0200 Subject: [PATCH 046/340] romanian-issues-259: revert a test --- tests/test_ro.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_ro.py b/tests/test_ro.py index 007316f8..4089ddd0 100644 --- a/tests/test_ro.py +++ b/tests/test_ro.py @@ -124,6 +124,10 @@ def test_to_currency(self): 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 de lei și patruzeci de bani' @@ -146,8 +150,8 @@ def test_to_currency(self): num2words(22000, lang='ro', to='currency'), u'douăzeci și două de mii de lei') self.assertEqual( - num2words(13000, lang='ro', to='currency'), - u'treisprezece mii de lei') + 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 ' From ede1db8690c878d0d515617ff507e910bc89c7ad Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 16:38:39 +0300 Subject: [PATCH 047/340] updated tests --- tests/test_tr.py | 220 +++++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 103 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 6622ddc6..6d169f59 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -25,170 +25,184 @@ class Num2WordsTRTest(TestCase): def test_tr(self): # ref https://github.com/savoirfairelinux/num2words/issues/8 - 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(1, lang="tr", to="ordinal"), u"birinci") + self.assertEqual(num2words(2, lang="tr", to="ordinal"), u"ikinci") + self.assertEqual(num2words(9, lang="tr", to="ordinal"), u"dokuzuncu") + self.assertEqual(num2words(10, lang="tr", to="ordinal"), u"onuncu") + self.assertEqual(num2words(11, lang="tr", to="ordinal"), u"onbirinci") + self.assertEqual(num2words(44, lang="tr", to="ordinal"), u"kırkdördüncü") + self.assertEqual(num2words(100, lang="tr", to="ordinal"), u"yüzüncü") + self.assertEqual(num2words(101, lang="tr", to="ordinal"), u"yüzbirinci") + self.assertEqual(num2words(103, lang="tr", to="ordinal"), u"yüzüçüncü") + self.assertEqual(num2words(110, lang="tr", to="ordinal"), u"yüzonuncu") + self.assertEqual(num2words(111, lang="tr", to="ordinal"), u"yüzonbirinci") + self.assertEqual(num2words(1000, lang="tr", to="ordinal"), u"bininci") + self.assertEqual(num2words(1001, lang="tr", to="ordinal"), u"binbirinci") + self.assertEqual(num2words(1010, lang="tr", to="ordinal"), u"binonuncu") + self.assertEqual(num2words(1011, lang="tr", to="ordinal"), u"binonbirinci") + self.assertEqual(num2words(1100, lang="tr", to="ordinal"), u"binyüzüncü") + self.assertEqual(num2words(1110, lang="tr", to="ordinal"), u"binyüzonuncu") self.assertEqual( - num2words(2341, True, "tr"), u"ikibinüçyüzkırkbirinci" + num2words(2341, lang="tr", to="ordinal"), 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(10000, lang="tr", to="ordinal"), u"onbininci") + self.assertEqual(num2words(10010, lang="tr", to="ordinal"), u"onbinonuncu") + self.assertEqual(num2words(10100, lang="tr", to="ordinal"), u"onbinyüzüncü") + self.assertEqual(num2words(10110, lang="tr", to="ordinal"), u"onbinyüzonuncu") + self.assertEqual(num2words(11000, lang="tr", to="ordinal"), u"onbirbininci") + self.assertEqual(num2words(35000, lang="tr", to="ordinal"), u"otuzbeşbininci") self.assertEqual( - num2words(116331, True, "tr"), u"yüzonaltıbinüçyüzotuzbirinci" + num2words(116331, lang="tr", to="ordinal"), u"yüzonaltıbinüçyüzotuzbirinci" ) self.assertEqual( - num2words(116330, True, "tr"), u"yüzonaltıbinüçyüzotuzuncu" + num2words(116330, lang="tr", to="ordinal"), 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(100000, lang="tr", to="ordinal"), u"yüzbininci") + self.assertEqual(num2words(501000, lang="tr", to="ordinal"), u"beşyüzbirbininci") self.assertEqual( - num2words(1000111, True, "tr"), u"birmilyonyüzonbirinci" + num2words(1000111, lang="tr", to="ordinal"), u"birmilyonyüzonbirinci" ) self.assertEqual( - num2words(111000111, True, "tr"), u"yüzonbirmilyonyüzonbirinci" + num2words(111000111, lang="tr", to="ordinal"), u"yüzonbirmilyonyüzonbirinci" ) self.assertEqual( - num2words(111001111, True, "tr"), u"yüzonbirmilyonbinyüzonbirinci" + num2words(111001111, lang="tr", to="ordinal"), u"yüzonbirmilyonbinyüzonbirinci" ) self.assertEqual( - num2words(111111111, True, "tr"), + num2words(111111111, lang="tr", to="ordinal"), u"yüzonbirmilyonyüzonbirbinyüzonbirinci" ) - self.assertEqual(num2words(100001000, True, "tr"), u"yüzmilyonbininci") + self.assertEqual(num2words(100001000, lang="tr", to="ordinal"), u"yüzmilyonbininci") self.assertEqual( - num2words(100001001, True, "tr"), u"yüzmilyonbinbirinci" + num2words(100001001, lang="tr", to="ordinal"), u"yüzmilyonbinbirinci" ) self.assertEqual( - num2words(100010000, True, "tr"), u"yüzmilyononbininci" + num2words(100010000, lang="tr", to="ordinal"), u"yüzmilyononbininci" ) self.assertEqual( - num2words(100010001, True, "tr"), u"yüzmilyononbinbirinci" + num2words(100010001, lang="tr", to="ordinal"), u"yüzmilyononbinbirinci" ) self.assertEqual( - num2words(100011000, True, "tr"), u"yüzmilyononbirbininci" + num2words(100011000, lang="tr", to="ordinal"), u"yüzmilyononbirbininci" ) self.assertEqual( - num2words(100011001, True, "tr"), u"yüzmilyononbirbinbirinci" + num2words(100011001, lang="tr", to="ordinal"), u"yüzmilyononbirbinbirinci" ) self.assertEqual( - num2words(101011001, True, "tr"), u"yüzbirmilyononbirbinbirinci" + num2words(101011001, lang="tr", to="ordinal"), u"yüzbirmilyononbirbinbirinci" ) self.assertEqual( - num2words(101011010, True, "tr"), u"yüzbirmilyononbirbinonuncu" + num2words(101011010, lang="tr", to="ordinal"), u"yüzbirmilyononbirbinonuncu" ) self.assertEqual( - num2words(1101011010, True, "tr"), + num2words(1101011010, lang="tr", to="ordinal"), u"birmilyaryüzbirmilyononbirbinonuncu" ) self.assertEqual( - num2words(101101011010, True, "tr"), + num2words(101101011010, lang="tr", to="ordinal"), u"yüzbirmilyaryüzbirmilyononbirbinonuncu" ) self.assertEqual( - num2words(1000000000001, True, "tr"), u"birtrilyonbirinci" + num2words(1000000000001, lang="tr", to="ordinal"), 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"), + self.assertEqual(num2words(1, lang="tr", to="cardinal"), u"bir") + self.assertEqual(num2words(2, lang="tr", to="cardinal"), u"iki") + self.assertEqual(num2words(9, lang="tr", to="cardinal"), u"dokuz") + self.assertEqual(num2words(10, lang="tr", to="cardinal"), u"on") + self.assertEqual(num2words(11, lang="tr", to="cardinal"), u"onbir") + self.assertEqual(num2words(44, lang="tr", to="cardinal"), u"kırkdört") + self.assertEqual(num2words(100, lang="tr", to="cardinal"), u"yüz") + self.assertEqual(num2words(101, lang="tr", to="cardinal"), u"yüzbir") + self.assertEqual(num2words(103, lang="tr", to="cardinal"), u"yüzüç") + self.assertEqual(num2words(110, lang="tr", to="cardinal"), u"yüzon") + self.assertEqual(num2words(111, lang="tr", to="cardinal"), u"yüzonbir") + self.assertEqual(num2words(1000, lang="tr", to="cardinal"), u"bin") + self.assertEqual(num2words(1001, lang="tr", to="cardinal"), u"binbir") + self.assertEqual(num2words(1010, lang="tr", to="cardinal"), u"binon") + self.assertEqual(num2words(1011, lang="tr", to="cardinal"), u"binonbir") + self.assertEqual(num2words(1100, lang="tr", to="cardinal"), u"binyüz") + self.assertEqual(num2words(1110, lang="tr", to="cardinal"), u"binyüzon") + self.assertEqual(num2words(2341, lang="tr", to="cardinal"), u"ikibinüçyüzkırkbir") + self.assertEqual(num2words(10000, lang="tr", to="cardinal"), u"onbin") + self.assertEqual(num2words(10010, lang="tr", to="cardinal"), u"onbinon") + self.assertEqual(num2words(10100, lang="tr", to="cardinal"), u"onbinyüz") + self.assertEqual(num2words(10110, lang="tr", to="cardinal"), u"onbinyüzon") + self.assertEqual(num2words(11000, lang="tr", to="cardinal"), u"onbirbin") + self.assertEqual(num2words(35000, lang="tr", to="cardinal"), u"otuzbeşbin") + self.assertEqual( + num2words(116331, lang="tr", to="cardinal"), u"yüzonaltıbinüçyüzotuzbir" + ) + self.assertEqual( + num2words(116330, lang="tr", to="cardinal"), u"yüzonaltıbinüçyüzotuz" + ) + self.assertEqual(num2words(500000, lang="tr", to="cardinal"), u"beşyüzbin") + self.assertEqual(num2words(501000, lang="tr", to="cardinal"), u"beşyüzbirbin") + self.assertEqual(num2words(1000111, lang="tr", to="cardinal"), u"birmilyonyüzonbir") + self.assertEqual( + num2words(111000111, lang="tr", to="cardinal"), u"yüzonbirmilyonyüzonbir" + ) + self.assertEqual( + num2words(111001111, lang="tr", to="cardinal"), u"yüzonbirmilyonbinyüzonbir" + ) + self.assertEqual( + num2words(111111111, lang="tr", to="cardinal"), 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(100001000, lang="tr", to="cardinal"), u"yüzmilyonbin") + self.assertEqual(num2words(100001001, lang="tr", to="cardinal"), u"yüzmilyonbinbir") + self.assertEqual(num2words(100010000, lang="tr", to="cardinal"), u"yüzmilyononbin") self.assertEqual( - num2words(100010001, False, "tr"), u"yüzmilyononbinbir" + num2words(100010001, lang="tr", to="cardinal"), u"yüzmilyononbinbir" ) self.assertEqual( - num2words(100011000, False, "tr"), u"yüzmilyononbirbin" + num2words(100011000, lang="tr", to="cardinal"), u"yüzmilyononbirbin" ) self.assertEqual( - num2words(100011001, False, "tr"), u"yüzmilyononbirbinbir" + num2words(100011001, lang="tr", to="cardinal"), u"yüzmilyononbirbinbir" ) self.assertEqual( - num2words(101011001, False, "tr"), u"yüzbirmilyononbirbinbir" + num2words(101011001, lang="tr", to="cardinal"), u"yüzbirmilyononbirbinbir" ) self.assertEqual( - num2words(101011010, False, "tr"), u"yüzbirmilyononbirbinon" + num2words(101011010, lang="tr", to="cardinal"), u"yüzbirmilyononbirbinon" ) self.assertEqual( - num2words(1101011010, False, "tr"), + num2words(1101011010, lang="tr", to="cardinal"), u"birmilyaryüzbirmilyononbirbinon" ) self.assertEqual( - num2words(101101011010, False, "tr"), + num2words(101101011010, lang="tr", to="cardinal"), u"yüzbirmilyaryüzbirmilyononbirbinon" ) self.assertEqual( - num2words(1000000000001, False, "tr"), u"birtrilyonbir" + num2words(1000000000001, lang="tr", to="cardinal"), 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(0.01, lang="tr", to="cardinal"), u"sıfırvirgülbir") + self.assertEqual(num2words(0.1, lang="tr", to="cardinal"), u"sıfırvirgülon") + self.assertEqual(num2words(0.21, lang="tr", to="cardinal"), u"sıfırvirgülyirmibir") + self.assertEqual(num2words(1.01, lang="tr", to="cardinal"), u"birvirgülbir") + self.assertEqual(num2words(1.1, lang="tr", to="cardinal"), u"birvirgülon") + self.assertEqual(num2words(1.21, lang="tr", to="cardinal"), u"birvirgülyirmibir") self.assertEqual( - num2words(101101011010.02, False, "tr"), + num2words(101101011010.02, lang="tr", to="cardinal"), u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki" ) self.assertEqual( - num2words(101101011010.2, False, "tr"), + num2words(101101011010.2, lang="tr", to="cardinal"), u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi" ) + self.assertEqual(num2words(0, lang="tr", to="currency"), u'sıfırlira') + self.assertEqual(num2words(1.1, lang="tr", to="currency"), u'birliraonkuruş') + self.assertEqual(num2words(1.2, lang="tr", to="ordinal"), u'birvirgülyirmi') + self.assertEqual(num2words(1.3, lang="tr", to="ordinal"), u'birvirgülotuz') + self.assertEqual(num2words(2000, lang="tr", to="currency"), u'ikibinlira') + self.assertEqual(num2words(3000, lang="tr", to="ordinal"), u'üçbin') + self.assertEqual(num2words(110000, lang="tr", to="currency"), u'yüzonbinlira') + self.assertEqual(num2words(120000, lang="tr", to="ordinal"), u'yüzyirmibin') + self.assertEqual(num2words(1002000, lang="tr", to="currency"), u'birmilyonikibinlira') + self.assertEqual(num2words(1002001, lang="tr", to="currency"), u'birmilyonikibinbirlira') + self.assertEqual(num2words(1002002, lang="tr", to="ordinal"), u'birmilyonikibiniki') + self.assertEqual(num2words(1003000, lang="tr", to="ordinal"), u'birmilyonüçbin') + self.assertEqual(num2words(1100000, lang="tr", to="currency"), u'birmilyonyüzbin') + self.assertEqual(num2words(1200000, lang="tr", to="ordinal"), u'birmilyonikiyüzbin') From 9b8a5412248325adfce35eb30ae61e2b682e926e Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 16:45:01 +0300 Subject: [PATCH 048/340] updated tests --- num2words/lang_TR.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 3f43fedd..df1f7cdd 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -830,6 +830,8 @@ def to_splitnum(self, val): found = 1 def to_currency(self, value): + if int(value) == 0: + return self.ZERO + self.CURRENCY_UNIT[0] valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: return valueparts[0] + self.CURRENCY_UNIT[0] From 12ef620b29740496a04decc1bb7c374c07eb75dc Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 16:49:40 +0300 Subject: [PATCH 049/340] updated tests --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index df1f7cdd..a53495cb 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -831,7 +831,7 @@ def to_splitnum(self, val): def to_currency(self, value): if int(value) == 0: - return self.ZERO + self.CURRENCY_UNIT[0] + return self.CURRENCY_UNIT[0].join(self.ZERO) valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: return valueparts[0] + self.CURRENCY_UNIT[0] From 8e19dd584bfae906bbd3d9f8a6df1ee56cd44dd1 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 16:59:02 +0300 Subject: [PATCH 050/340] updated tests --- num2words/lang_TR.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index a53495cb..097c2b61 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -24,8 +24,8 @@ 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." @@ -831,10 +831,10 @@ def to_splitnum(self, val): def to_currency(self, value): if int(value) == 0: - return self.CURRENCY_UNIT[0].join(self.ZERO) + return self.CURRENCY_UNIT.join(self.ZERO) 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 From 1514514ed997c9d6b7e1d8f922c4cf5a3d57da07 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:06:07 +0300 Subject: [PATCH 051/340] updated tests --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 097c2b61..8acc7127 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -831,7 +831,7 @@ def to_splitnum(self, val): def to_currency(self, value): if int(value) == 0: - return self.CURRENCY_UNIT.join(self.ZERO) + return "{}{}".format(self.CURRENCY_UNIT, self.ZERO) valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: return valueparts[0] + self.CURRENCY_UNIT From 0b22ac19503d46693b3f8e2472a6b4b4821c629d Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:11:07 +0300 Subject: [PATCH 052/340] updated tests --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 8acc7127..31660db6 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -34,7 +34,7 @@ def __init__(self): self.exclude_title = [] self.DECIMAL_SIGN = (",",) self.ORDINAL_SIGN = (".",) - self.ZERO = (u"sıfır",) + self.ZERO = u"sıfır" self.CARDINAL_ONES = { "1": u"bir", "2": u"iki", From 7c6a7161659c069b31691438cfd131a3be07a0f0 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:12:13 +0300 Subject: [PATCH 053/340] updated tests --- num2words/lang_TR.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 31660db6..48477f65 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -32,8 +32,8 @@ def __init__(self): 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.DECIMAL_SIGN = "," + self.ORDINAL_SIGN = "." self.ZERO = u"sıfır" self.CARDINAL_ONES = { "1": u"bir", @@ -444,7 +444,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 From 2c629f8349a13f2122fa951212a6faba9941b209 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:16:02 +0300 Subject: [PATCH 054/340] updated tests --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 48477f65..bed34f5c 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -831,7 +831,7 @@ def to_splitnum(self, val): def to_currency(self, value): if int(value) == 0: - return "{}{}".format(self.CURRENCY_UNIT, self.ZERO) + return "{}{}".format(self.ZERO, self.CURRENCY_UNIT) valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: return valueparts[0] + self.CURRENCY_UNIT From 2fae9512ce6063865168b53c709cd6f9f8d7fd53 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:26:26 +0300 Subject: [PATCH 055/340] updated tests --- tests/test_tr.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 6d169f59..7eabcd51 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -194,15 +194,15 @@ def test_tr(self): ) self.assertEqual(num2words(0, lang="tr", to="currency"), u'sıfırlira') self.assertEqual(num2words(1.1, lang="tr", to="currency"), u'birliraonkuruş') - self.assertEqual(num2words(1.2, lang="tr", to="ordinal"), u'birvirgülyirmi') - self.assertEqual(num2words(1.3, lang="tr", to="ordinal"), u'birvirgülotuz') + self.assertEqual(num2words(1.2, lang="tr", to="ordinal"), u'') + self.assertEqual(num2words(1.3, lang="tr", to="ordinal"), u'') self.assertEqual(num2words(2000, lang="tr", to="currency"), u'ikibinlira') - self.assertEqual(num2words(3000, lang="tr", to="ordinal"), u'üçbin') + self.assertEqual(num2words(3000, lang="tr", to="ordinal"), u'üçbininci') self.assertEqual(num2words(110000, lang="tr", to="currency"), u'yüzonbinlira') - self.assertEqual(num2words(120000, lang="tr", to="ordinal"), u'yüzyirmibin') + self.assertEqual(num2words(120000, lang="tr", to="ordinal"), u'yüzyirmibininci') self.assertEqual(num2words(1002000, lang="tr", to="currency"), u'birmilyonikibinlira') self.assertEqual(num2words(1002001, lang="tr", to="currency"), u'birmilyonikibinbirlira') - self.assertEqual(num2words(1002002, lang="tr", to="ordinal"), u'birmilyonikibiniki') - self.assertEqual(num2words(1003000, lang="tr", to="ordinal"), u'birmilyonüçbin') + self.assertEqual(num2words(1002002, lang="tr", to="ordinal"), u'birmilyonikibinikinci') + self.assertEqual(num2words(1003000, lang="tr", to="ordinal"), u'birmilyonüçbininci') self.assertEqual(num2words(1100000, lang="tr", to="currency"), u'birmilyonyüzbin') - self.assertEqual(num2words(1200000, lang="tr", to="ordinal"), u'birmilyonikiyüzbin') + self.assertEqual(num2words(1200000, lang="tr", to="ordinal"), u'birmilyonikiyüzbininci') From f5c07d714da3880ac85ec7f923decefe7aefc9e5 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 17:35:32 +0300 Subject: [PATCH 056/340] updated tests --- tests/test_tr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 7eabcd51..875cf7f3 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -204,5 +204,5 @@ def test_tr(self): self.assertEqual(num2words(1002001, lang="tr", to="currency"), u'birmilyonikibinbirlira') self.assertEqual(num2words(1002002, lang="tr", to="ordinal"), u'birmilyonikibinikinci') self.assertEqual(num2words(1003000, lang="tr", to="ordinal"), u'birmilyonüçbininci') - self.assertEqual(num2words(1100000, lang="tr", to="currency"), u'birmilyonyüzbin') + self.assertEqual(num2words(1100000, lang="tr", to="currency"), u'birmilyonyüzbinlira') self.assertEqual(num2words(1200000, lang="tr", to="ordinal"), u'birmilyonikiyüzbininci') From a7971f11561eb52375ea4901502fe53f8c31e3e9 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 18:46:34 +0300 Subject: [PATCH 057/340] updated tests --- num2words/lang_TR.py | 2 +- tests/test_tr.py | 296 +++++++++++++++++-------------------------- 2 files changed, 117 insertions(+), 181 deletions(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index bed34f5c..51f415b9 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -831,7 +831,7 @@ def to_splitnum(self, val): def to_currency(self, value): if int(value) == 0: - return "{}{}".format(self.ZERO, self.CURRENCY_UNIT) + return u"bedelsiz" valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: return valueparts[0] + self.CURRENCY_UNIT diff --git a/tests/test_tr.py b/tests/test_tr.py index 875cf7f3..aa0e5dc7 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -25,184 +25,120 @@ class Num2WordsTRTest(TestCase): def test_tr(self): # ref https://github.com/savoirfairelinux/num2words/issues/8 - self.assertEqual(num2words(1, lang="tr", to="ordinal"), u"birinci") - self.assertEqual(num2words(2, lang="tr", to="ordinal"), u"ikinci") - self.assertEqual(num2words(9, lang="tr", to="ordinal"), u"dokuzuncu") - self.assertEqual(num2words(10, lang="tr", to="ordinal"), u"onuncu") - self.assertEqual(num2words(11, lang="tr", to="ordinal"), u"onbirinci") - self.assertEqual(num2words(44, lang="tr", to="ordinal"), u"kırkdördüncü") - self.assertEqual(num2words(100, lang="tr", to="ordinal"), u"yüzüncü") - self.assertEqual(num2words(101, lang="tr", to="ordinal"), u"yüzbirinci") - self.assertEqual(num2words(103, lang="tr", to="ordinal"), u"yüzüçüncü") - self.assertEqual(num2words(110, lang="tr", to="ordinal"), u"yüzonuncu") - self.assertEqual(num2words(111, lang="tr", to="ordinal"), u"yüzonbirinci") - self.assertEqual(num2words(1000, lang="tr", to="ordinal"), u"bininci") - self.assertEqual(num2words(1001, lang="tr", to="ordinal"), u"binbirinci") - self.assertEqual(num2words(1010, lang="tr", to="ordinal"), u"binonuncu") - self.assertEqual(num2words(1011, lang="tr", to="ordinal"), u"binonbirinci") - self.assertEqual(num2words(1100, lang="tr", to="ordinal"), u"binyüzüncü") - self.assertEqual(num2words(1110, lang="tr", to="ordinal"), u"binyüzonuncu") - self.assertEqual( - num2words(2341, lang="tr", to="ordinal"), u"ikibinüçyüzkırkbirinci" - ) - self.assertEqual(num2words(10000, lang="tr", to="ordinal"), u"onbininci") - self.assertEqual(num2words(10010, lang="tr", to="ordinal"), u"onbinonuncu") - self.assertEqual(num2words(10100, lang="tr", to="ordinal"), u"onbinyüzüncü") - self.assertEqual(num2words(10110, lang="tr", to="ordinal"), u"onbinyüzonuncu") - self.assertEqual(num2words(11000, lang="tr", to="ordinal"), u"onbirbininci") - self.assertEqual(num2words(35000, lang="tr", to="ordinal"), u"otuzbeşbininci") - self.assertEqual( - num2words(116331, lang="tr", to="ordinal"), u"yüzonaltıbinüçyüzotuzbirinci" - ) - self.assertEqual( - num2words(116330, lang="tr", to="ordinal"), u"yüzonaltıbinüçyüzotuzuncu" - ) - self.assertEqual(num2words(100000, lang="tr", to="ordinal"), u"yüzbininci") - self.assertEqual(num2words(501000, lang="tr", to="ordinal"), u"beşyüzbirbininci") - self.assertEqual( - num2words(1000111, lang="tr", to="ordinal"), u"birmilyonyüzonbirinci" - ) - self.assertEqual( - num2words(111000111, lang="tr", to="ordinal"), u"yüzonbirmilyonyüzonbirinci" - ) - self.assertEqual( - num2words(111001111, lang="tr", to="ordinal"), u"yüzonbirmilyonbinyüzonbirinci" - ) - self.assertEqual( - num2words(111111111, lang="tr", to="ordinal"), - u"yüzonbirmilyonyüzonbirbinyüzonbirinci" - ) - self.assertEqual(num2words(100001000, lang="tr", to="ordinal"), u"yüzmilyonbininci") - self.assertEqual( - num2words(100001001, lang="tr", to="ordinal"), u"yüzmilyonbinbirinci" - ) - self.assertEqual( - num2words(100010000, lang="tr", to="ordinal"), u"yüzmilyononbininci" - ) - self.assertEqual( - num2words(100010001, lang="tr", to="ordinal"), u"yüzmilyononbinbirinci" - ) - self.assertEqual( - num2words(100011000, lang="tr", to="ordinal"), u"yüzmilyononbirbininci" - ) - self.assertEqual( - num2words(100011001, lang="tr", to="ordinal"), u"yüzmilyononbirbinbirinci" - ) - self.assertEqual( - num2words(101011001, lang="tr", to="ordinal"), u"yüzbirmilyononbirbinbirinci" - ) - self.assertEqual( - num2words(101011010, lang="tr", to="ordinal"), u"yüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(1101011010, lang="tr", to="ordinal"), - u"birmilyaryüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(101101011010, lang="tr", to="ordinal"), - u"yüzbirmilyaryüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(1000000000001, lang="tr", to="ordinal"), u"birtrilyonbirinci" - ) + testcases = [ + {"number": 0, "lang": "tr", "to": "currency", "response": u"bedelsiz"}, + {"number": 1.1, "lang": "tr", "to": "currency", "response": u"birliraonkuruş"}, + {"number": 2000, "lang": "tr", "to": "currency", "response": u"ikibinlira"}, + {"number": 110000, "lang": "tr", "to": "currency", "response": u"yüzonbinlira"}, + {"number": 1002000, "lang": "tr", "to": "currency", "response": u"birmilyonikibinlira"}, + {"number": 1002001, "lang": "tr", "to": "currency", "response": u"birmilyonikibinbirlira"}, + {"number": 1100000, "lang": "tr", "to": "currency", "response": u"birmilyonyüzbinlira"}, + {"number": 1, "lang": "tr", "to": "ordinal", "response": u"birinci"}, + {"number": 2, "lang": "tr", "to": "ordinal", "response": u"ikinci"}, + {"number": 9, "lang": "tr", "to": "ordinal", "response": u"dokuzuncu"}, + {"number": 10, "lang": "tr", "to": "ordinal", "response": u"onuncu"}, + {"number": 11, "lang": "tr", "to": "ordinal", "response": u"onbirinci"}, + {"number": 44, "lang": "tr", "to": "ordinal", "response": u"kırkdördüncü"}, + {"number": 100, "lang": "tr", "to": "ordinal", "response": u"yüzüncü"}, + {"number": 101, "lang": "tr", "to": "ordinal", "response": u"yüzbirinci"}, + {"number": 103, "lang": "tr", "to": "ordinal", "response": u"yüzüçüncü"}, + {"number": 110, "lang": "tr", "to": "ordinal", "response": u"yüzonuncu"}, + {"number": 111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirinci"}, + {"number": 1000, "lang": "tr", "to": "ordinal", "response": u"bininci"}, + {"number": 1001, "lang": "tr", "to": "ordinal", "response": u"binbirinci"}, + {"number": 1010, "lang": "tr", "to": "ordinal", "response": u"binonuncu"}, + {"number": 1011, "lang": "tr", "to": "ordinal", "response": u"binonbirinci"}, + {"number": 1100, "lang": "tr", "to": "ordinal", "response": u"binyüzüncü"}, + {"number": 1110, "lang": "tr", "to": "ordinal", "response": u"binyüzonuncu"}, + {"number": 2341, "lang": "tr", "to": "ordinal", "response": u"ikibinüçyüzkırkbirinci"}, + {"number": 10000, "lang": "tr", "to": "ordinal", "response": u"onbininci"}, + {"number": 10010, "lang": "tr", "to": "ordinal", "response": u"onbinonuncu"}, + {"number": 10100, "lang": "tr", "to": "ordinal", "response": u"onbinyüzüncü"}, + {"number": 10110, "lang": "tr", "to": "ordinal", "response": u"onbinyüzonuncu"}, + {"number": 11000, "lang": "tr", "to": "ordinal", "response": u"onbirbininci"}, + {"number": 35000, "lang": "tr", "to": "ordinal", "response": u"otuzbeşbininci"}, + {"number": 116331, "lang": "tr", "to": "ordinal", "response": u"yüzonaltıbinüçyüzotuzbirinci"}, + {"number": 116330, "lang": "tr", "to": "ordinal", "response": u"yüzonaltıbinüçyüzotuzuncu"}, + {"number": 100000, "lang": "tr", "to": "ordinal", "response": u"yüzbininci"}, + {"number": 501000, "lang": "tr", "to": "ordinal", "response": u"beşyüzbirbininci"}, + {"number": 1000111, "lang": "tr", "to": "ordinal", "response": u"birmilyonyüzonbirinci"}, + {"number": 111000111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonyüzonbirinci"}, + {"number": 111001111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonbinyüzonbirinci"}, + {"number": 111111111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonyüzonbirbinyüzonbirinci"}, + {"number": 100001000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyonbininci"}, + {"number": 100001001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyonbinbirinci"}, + {"number": 100010000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbininci"}, + {"number": 100010001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbinbirinci"}, + {"number": 100011000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbirbininci"}, + {"number": 100011001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbirbinbirinci"}, + {"number": 101011001, "lang": "tr", "to": "ordinal", "response": u"yüzbirmilyononbirbinbirinci"}, + {"number": 101011010, "lang": "tr", "to": "ordinal", "response": u"yüzbirmilyononbirbinonuncu"}, + {"number": 1101011010, "lang": "tr", "to": "ordinal", "response": u"birmilyaryüzbirmilyononbirbinonuncu"}, + {"number": 101101011010, "lang": "tr", "to": "ordinal", + "response": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, + {"number": 1000000000001, "lang": "tr", "to": "ordinal", "response": u"birtrilyonbirinci"}, + {"number": 1.2, "lang": "tr", "to": "ordinal", "response": u""}, + {"number": 1.3, "lang": "tr", "to": "ordinal", "response": u""}, + {"number": 3000, "lang": "tr", "to": "ordinal", "response": u"üçbininci"}, + {"number": 120000, "lang": "tr", "to": "ordinal", "response": u"yüzyirmibininci"}, + {"number": 1002002, "lang": "tr", "to": "ordinal", "response": u"birmilyonikibinikinci"}, + {"number": 1003000, "lang": "tr", "to": "ordinal", "response": u"birmilyonüçbininci"}, + {"number": 1200000, "lang": "tr", "to": "ordinal", "response": u"birmilyonikiyüzbininci"}, + {"number": 1, "lang": "tr", "to": "cardinal", "response": u"bir"}, + {"number": 2, "lang": "tr", "to": "cardinal", "response": u"iki"}, + {"number": 9, "lang": "tr", "to": "cardinal", "response": u"dokuz"}, + {"number": 10, "lang": "tr", "to": "cardinal", "response": u"on"}, + {"number": 11, "lang": "tr", "to": "cardinal", "response": u"onbir"}, + {"number": 44, "lang": "tr", "to": "cardinal", "response": u"kırkdört"}, + {"number": 100, "lang": "tr", "to": "cardinal", "response": u"yüz"}, + {"number": 101, "lang": "tr", "to": "cardinal", "response": u"yüzbir"}, + {"number": 103, "lang": "tr", "to": "cardinal", "response": u"yüzüç"}, + {"number": 110, "lang": "tr", "to": "cardinal", "response": u"yüzon"}, + {"number": 111, "lang": "tr", "to": "cardinal", "response": u"yüzonbir"}, + {"number": 1000, "lang": "tr", "to": "cardinal", "response": u"bin"}, + {"number": 1001, "lang": "tr", "to": "cardinal", "response": u"binbir"}, + {"number": 1010, "lang": "tr", "to": "cardinal", "response": u"binon"}, + {"number": 1011, "lang": "tr", "to": "cardinal", "response": u"binonbir"}, + {"number": 1100, "lang": "tr", "to": "cardinal", "response": u"binyüz"}, + {"number": 1110, "lang": "tr", "to": "cardinal", "response": u"binyüzon"}, + {"number": 2341, "lang": "tr", "to": "cardinal", "response": u"ikibinüçyüzkırkbir"}, + {"number": 10000, "lang": "tr", "to": "cardinal", "response": u"onbin"}, + {"number": 10010, "lang": "tr", "to": "cardinal", "response": u"onbinon"}, + {"number": 10100, "lang": "tr", "to": "cardinal", "response": u"onbinyüz"}, + {"number": 10110, "lang": "tr", "to": "cardinal", "response": u"onbinyüzon"}, + {"number": 11000, "lang": "tr", "to": "cardinal", "response": u"onbirbin"}, + {"number": 35000, "lang": "tr", "to": "cardinal", "response": u"otuzbeşbin"}, + {"number": 116331, "lang": "tr", "to": "cardinal", "response": u"yüzonaltıbinüçyüzotuzbir"}, + {"number": 116330, "lang": "tr", "to": "cardinal", "response": u"yüzonaltıbinüçyüzotuz"}, + {"number": 500000, "lang": "tr", "to": "cardinal", "response": u"beşyüzbin"}, + {"number": 501000, "lang": "tr", "to": "cardinal", "response": u"beşyüzbirbin"}, + {"number": 1000111, "lang": "tr", "to": "cardinal", "response": u"birmilyonyüzonbir"}, + {"number": 111000111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonyüzonbir"}, + {"number": 111001111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonbinyüzonbir"}, + {"number": 111111111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonyüzonbirbinyüzonbir"}, + {"number": 100001000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbin"}, + {"number": 100001001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, + {"number": 100010000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbin"}, + {"number": 100010001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbinbir"}, + {"number": 100011000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbirbin"}, + {"number": 100011001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbirbinbir"}, + {"number": 101011001, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyononbirbinbir"}, + {"number": 101011010, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyononbirbinon"}, + {"number": 1101011010, "lang": "tr", "to": "cardinal", "response": u"birmilyaryüzbirmilyononbirbinon"}, + {"number": 101101011010, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyaryüzbirmilyononbirbinon"}, + {"number": 100001001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, + {"number": 1000000000001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, + {"number": 0.01, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülbir"}, + {"number": 0.21, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülyirmibir"}, + {"number": 0.1, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülon"}, + {"number": 1.01, "lang": "tr", "to": "cardinal", "response": u"birvirgülbir"}, + {"number": 1.1, "lang": "tr", "to": "cardinal", "response": u"birvirgülon"}, + {"number": 1.21, "lang": "tr", "to": "cardinal", "response": u"birvirgülyirmibir"}, + {"number": 101101011010.02, "lang": "tr", "to": "cardinal", + "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, + {"number": 101101011010.2, "lang": "tr", "to": "cardinal", + "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"}, + ] - self.assertEqual(num2words(1, lang="tr", to="cardinal"), u"bir") - self.assertEqual(num2words(2, lang="tr", to="cardinal"), u"iki") - self.assertEqual(num2words(9, lang="tr", to="cardinal"), u"dokuz") - self.assertEqual(num2words(10, lang="tr", to="cardinal"), u"on") - self.assertEqual(num2words(11, lang="tr", to="cardinal"), u"onbir") - self.assertEqual(num2words(44, lang="tr", to="cardinal"), u"kırkdört") - self.assertEqual(num2words(100, lang="tr", to="cardinal"), u"yüz") - self.assertEqual(num2words(101, lang="tr", to="cardinal"), u"yüzbir") - self.assertEqual(num2words(103, lang="tr", to="cardinal"), u"yüzüç") - self.assertEqual(num2words(110, lang="tr", to="cardinal"), u"yüzon") - self.assertEqual(num2words(111, lang="tr", to="cardinal"), u"yüzonbir") - self.assertEqual(num2words(1000, lang="tr", to="cardinal"), u"bin") - self.assertEqual(num2words(1001, lang="tr", to="cardinal"), u"binbir") - self.assertEqual(num2words(1010, lang="tr", to="cardinal"), u"binon") - self.assertEqual(num2words(1011, lang="tr", to="cardinal"), u"binonbir") - self.assertEqual(num2words(1100, lang="tr", to="cardinal"), u"binyüz") - self.assertEqual(num2words(1110, lang="tr", to="cardinal"), u"binyüzon") - self.assertEqual(num2words(2341, lang="tr", to="cardinal"), u"ikibinüçyüzkırkbir") - self.assertEqual(num2words(10000, lang="tr", to="cardinal"), u"onbin") - self.assertEqual(num2words(10010, lang="tr", to="cardinal"), u"onbinon") - self.assertEqual(num2words(10100, lang="tr", to="cardinal"), u"onbinyüz") - self.assertEqual(num2words(10110, lang="tr", to="cardinal"), u"onbinyüzon") - self.assertEqual(num2words(11000, lang="tr", to="cardinal"), u"onbirbin") - self.assertEqual(num2words(35000, lang="tr", to="cardinal"), u"otuzbeşbin") - self.assertEqual( - num2words(116331, lang="tr", to="cardinal"), u"yüzonaltıbinüçyüzotuzbir" - ) - self.assertEqual( - num2words(116330, lang="tr", to="cardinal"), u"yüzonaltıbinüçyüzotuz" - ) - self.assertEqual(num2words(500000, lang="tr", to="cardinal"), u"beşyüzbin") - self.assertEqual(num2words(501000, lang="tr", to="cardinal"), u"beşyüzbirbin") - self.assertEqual(num2words(1000111, lang="tr", to="cardinal"), u"birmilyonyüzonbir") - self.assertEqual( - num2words(111000111, lang="tr", to="cardinal"), u"yüzonbirmilyonyüzonbir" - ) - self.assertEqual( - num2words(111001111, lang="tr", to="cardinal"), u"yüzonbirmilyonbinyüzonbir" - ) - self.assertEqual( - num2words(111111111, lang="tr", to="cardinal"), - u"yüzonbirmilyonyüzonbirbinyüzonbir" - ) - self.assertEqual(num2words(100001000, lang="tr", to="cardinal"), u"yüzmilyonbin") - self.assertEqual(num2words(100001001, lang="tr", to="cardinal"), u"yüzmilyonbinbir") - self.assertEqual(num2words(100010000, lang="tr", to="cardinal"), u"yüzmilyononbin") - self.assertEqual( - num2words(100010001, lang="tr", to="cardinal"), u"yüzmilyononbinbir" - ) - self.assertEqual( - num2words(100011000, lang="tr", to="cardinal"), u"yüzmilyononbirbin" - ) - self.assertEqual( - num2words(100011001, lang="tr", to="cardinal"), u"yüzmilyononbirbinbir" - ) - self.assertEqual( - num2words(101011001, lang="tr", to="cardinal"), u"yüzbirmilyononbirbinbir" - ) - self.assertEqual( - num2words(101011010, lang="tr", to="cardinal"), u"yüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(1101011010, lang="tr", to="cardinal"), - u"birmilyaryüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(101101011010, lang="tr", to="cardinal"), - u"yüzbirmilyaryüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(1000000000001, lang="tr", to="cardinal"), u"birtrilyonbir" - ) - self.assertEqual(num2words(0.01, lang="tr", to="cardinal"), u"sıfırvirgülbir") - self.assertEqual(num2words(0.1, lang="tr", to="cardinal"), u"sıfırvirgülon") - self.assertEqual(num2words(0.21, lang="tr", to="cardinal"), u"sıfırvirgülyirmibir") - self.assertEqual(num2words(1.01, lang="tr", to="cardinal"), u"birvirgülbir") - self.assertEqual(num2words(1.1, lang="tr", to="cardinal"), u"birvirgülon") - self.assertEqual(num2words(1.21, lang="tr", to="cardinal"), u"birvirgülyirmibir") - self.assertEqual( - num2words(101101011010.02, lang="tr", to="cardinal"), - u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki" - ) - self.assertEqual( - num2words(101101011010.2, lang="tr", to="cardinal"), - u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi" - ) - self.assertEqual(num2words(0, lang="tr", to="currency"), u'sıfırlira') - self.assertEqual(num2words(1.1, lang="tr", to="currency"), u'birliraonkuruş') - self.assertEqual(num2words(1.2, lang="tr", to="ordinal"), u'') - self.assertEqual(num2words(1.3, lang="tr", to="ordinal"), u'') - self.assertEqual(num2words(2000, lang="tr", to="currency"), u'ikibinlira') - self.assertEqual(num2words(3000, lang="tr", to="ordinal"), u'üçbininci') - self.assertEqual(num2words(110000, lang="tr", to="currency"), u'yüzonbinlira') - self.assertEqual(num2words(120000, lang="tr", to="ordinal"), u'yüzyirmibininci') - self.assertEqual(num2words(1002000, lang="tr", to="currency"), u'birmilyonikibinlira') - self.assertEqual(num2words(1002001, lang="tr", to="currency"), u'birmilyonikibinbirlira') - self.assertEqual(num2words(1002002, lang="tr", to="ordinal"), u'birmilyonikibinikinci') - self.assertEqual(num2words(1003000, lang="tr", to="ordinal"), u'birmilyonüçbininci') - self.assertEqual(num2words(1100000, lang="tr", to="currency"), u'birmilyonyüzbinlira') - self.assertEqual(num2words(1200000, lang="tr", to="ordinal"), u'birmilyonikiyüzbininci') + for casedata in testcases: + self.assertEqual(num2words(casedata.number, lang=casedata.lang, to=casedata.to), casedata.response) From 739f02d83010921cb30f05bb0ddb0ab1b3ca4530 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 18:55:38 +0300 Subject: [PATCH 058/340] updated tests --- tests/test_tr.py | 222 +++++++++++++++++++++++------------------------ 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index aa0e5dc7..9737d632 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -26,119 +26,119 @@ def test_tr(self): # ref https://github.com/savoirfairelinux/num2words/issues/8 testcases = [ - {"number": 0, "lang": "tr", "to": "currency", "response": u"bedelsiz"}, - {"number": 1.1, "lang": "tr", "to": "currency", "response": u"birliraonkuruş"}, - {"number": 2000, "lang": "tr", "to": "currency", "response": u"ikibinlira"}, - {"number": 110000, "lang": "tr", "to": "currency", "response": u"yüzonbinlira"}, - {"number": 1002000, "lang": "tr", "to": "currency", "response": u"birmilyonikibinlira"}, - {"number": 1002001, "lang": "tr", "to": "currency", "response": u"birmilyonikibinbirlira"}, - {"number": 1100000, "lang": "tr", "to": "currency", "response": u"birmilyonyüzbinlira"}, - {"number": 1, "lang": "tr", "to": "ordinal", "response": u"birinci"}, - {"number": 2, "lang": "tr", "to": "ordinal", "response": u"ikinci"}, - {"number": 9, "lang": "tr", "to": "ordinal", "response": u"dokuzuncu"}, - {"number": 10, "lang": "tr", "to": "ordinal", "response": u"onuncu"}, - {"number": 11, "lang": "tr", "to": "ordinal", "response": u"onbirinci"}, - {"number": 44, "lang": "tr", "to": "ordinal", "response": u"kırkdördüncü"}, - {"number": 100, "lang": "tr", "to": "ordinal", "response": u"yüzüncü"}, - {"number": 101, "lang": "tr", "to": "ordinal", "response": u"yüzbirinci"}, - {"number": 103, "lang": "tr", "to": "ordinal", "response": u"yüzüçüncü"}, - {"number": 110, "lang": "tr", "to": "ordinal", "response": u"yüzonuncu"}, - {"number": 111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirinci"}, - {"number": 1000, "lang": "tr", "to": "ordinal", "response": u"bininci"}, - {"number": 1001, "lang": "tr", "to": "ordinal", "response": u"binbirinci"}, - {"number": 1010, "lang": "tr", "to": "ordinal", "response": u"binonuncu"}, - {"number": 1011, "lang": "tr", "to": "ordinal", "response": u"binonbirinci"}, - {"number": 1100, "lang": "tr", "to": "ordinal", "response": u"binyüzüncü"}, - {"number": 1110, "lang": "tr", "to": "ordinal", "response": u"binyüzonuncu"}, - {"number": 2341, "lang": "tr", "to": "ordinal", "response": u"ikibinüçyüzkırkbirinci"}, - {"number": 10000, "lang": "tr", "to": "ordinal", "response": u"onbininci"}, - {"number": 10010, "lang": "tr", "to": "ordinal", "response": u"onbinonuncu"}, - {"number": 10100, "lang": "tr", "to": "ordinal", "response": u"onbinyüzüncü"}, - {"number": 10110, "lang": "tr", "to": "ordinal", "response": u"onbinyüzonuncu"}, - {"number": 11000, "lang": "tr", "to": "ordinal", "response": u"onbirbininci"}, - {"number": 35000, "lang": "tr", "to": "ordinal", "response": u"otuzbeşbininci"}, - {"number": 116331, "lang": "tr", "to": "ordinal", "response": u"yüzonaltıbinüçyüzotuzbirinci"}, - {"number": 116330, "lang": "tr", "to": "ordinal", "response": u"yüzonaltıbinüçyüzotuzuncu"}, - {"number": 100000, "lang": "tr", "to": "ordinal", "response": u"yüzbininci"}, - {"number": 501000, "lang": "tr", "to": "ordinal", "response": u"beşyüzbirbininci"}, - {"number": 1000111, "lang": "tr", "to": "ordinal", "response": u"birmilyonyüzonbirinci"}, - {"number": 111000111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonyüzonbirinci"}, - {"number": 111001111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonbinyüzonbirinci"}, - {"number": 111111111, "lang": "tr", "to": "ordinal", "response": u"yüzonbirmilyonyüzonbirbinyüzonbirinci"}, - {"number": 100001000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyonbininci"}, - {"number": 100001001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyonbinbirinci"}, - {"number": 100010000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbininci"}, - {"number": 100010001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbinbirinci"}, - {"number": 100011000, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbirbininci"}, - {"number": 100011001, "lang": "tr", "to": "ordinal", "response": u"yüzmilyononbirbinbirinci"}, - {"number": 101011001, "lang": "tr", "to": "ordinal", "response": u"yüzbirmilyononbirbinbirinci"}, - {"number": 101011010, "lang": "tr", "to": "ordinal", "response": u"yüzbirmilyononbirbinonuncu"}, - {"number": 1101011010, "lang": "tr", "to": "ordinal", "response": u"birmilyaryüzbirmilyononbirbinonuncu"}, - {"number": 101101011010, "lang": "tr", "to": "ordinal", + {"test": 0, "lang": "tr", "to": "currency", "expected": u"bedelsiz"}, + {"test": 1.1, "lang": "tr", "to": "currency", "expected": u"birliraonkuruş"}, + {"test": 2000, "lang": "tr", "to": "currency", "expected": u"ikibinlira"}, + {"test": 110000, "lang": "tr", "to": "currency", "expected": u"yüzonbinlira"}, + {"test": 1002000, "lang": "tr", "to": "currency", "expected": u"birmilyonikibinlira"}, + {"test": 1002001, "lang": "tr", "to": "currency", "expected": u"birmilyonikibinbirlira"}, + {"test": 1100000, "lang": "tr", "to": "currency", "expected": u"birmilyonyüzbinlira"}, + {"test": 1, "lang": "tr", "to": "ordinal", "expected": u"birinci"}, + {"test": 2, "lang": "tr", "to": "ordinal", "expected": u"ikinci"}, + {"test": 9, "lang": "tr", "to": "ordinal", "expected": u"dokuzuncu"}, + {"test": 10, "lang": "tr", "to": "ordinal", "expected": u"onuncu"}, + {"test": 11, "lang": "tr", "to": "ordinal", "expected": u"onbirinci"}, + {"test": 44, "lang": "tr", "to": "ordinal", "expected": u"kırkdördüncü"}, + {"test": 100, "lang": "tr", "to": "ordinal", "expected": u"yüzüncü"}, + {"test": 101, "lang": "tr", "to": "ordinal", "expected": u"yüzbirinci"}, + {"test": 103, "lang": "tr", "to": "ordinal", "expected": u"yüzüçüncü"}, + {"test": 110, "lang": "tr", "to": "ordinal", "expected": u"yüzonuncu"}, + {"test": 111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirinci"}, + {"test": 1000, "lang": "tr", "to": "ordinal", "expected": u"bininci"}, + {"test": 1001, "lang": "tr", "to": "ordinal", "expected": u"binbirinci"}, + {"test": 1010, "lang": "tr", "to": "ordinal", "expected": u"binonuncu"}, + {"test": 1011, "lang": "tr", "to": "ordinal", "expected": u"binonbirinci"}, + {"test": 1100, "lang": "tr", "to": "ordinal", "expected": u"binyüzüncü"}, + {"test": 1110, "lang": "tr", "to": "ordinal", "expected": u"binyüzonuncu"}, + {"test": 2341, "lang": "tr", "to": "ordinal", "expected": u"ikibinüçyüzkırkbirinci"}, + {"test": 10000, "lang": "tr", "to": "ordinal", "expected": u"onbininci"}, + {"test": 10010, "lang": "tr", "to": "ordinal", "expected": u"onbinonuncu"}, + {"test": 10100, "lang": "tr", "to": "ordinal", "expected": u"onbinyüzüncü"}, + {"test": 10110, "lang": "tr", "to": "ordinal", "expected": u"onbinyüzonuncu"}, + {"test": 11000, "lang": "tr", "to": "ordinal", "expected": u"onbirbininci"}, + {"test": 35000, "lang": "tr", "to": "ordinal", "expected": u"otuzbeşbininci"}, + {"test": 116331, "lang": "tr", "to": "ordinal", "expected": u"yüzonaltıbinüçyüzotuzbirinci"}, + {"test": 116330, "lang": "tr", "to": "ordinal", "expected": u"yüzonaltıbinüçyüzotuzuncu"}, + {"test": 100000, "lang": "tr", "to": "ordinal", "expected": u"yüzbininci"}, + {"test": 501000, "lang": "tr", "to": "ordinal", "expected": u"beşyüzbirbininci"}, + {"test": 1000111, "lang": "tr", "to": "ordinal", "expected": u"birmilyonyüzonbirinci"}, + {"test": 111000111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonyüzonbirinci"}, + {"test": 111001111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonbinyüzonbirinci"}, + {"test": 111111111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonyüzonbirbinyüzonbirinci"}, + {"test": 100001000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyonbininci"}, + {"test": 100001001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyonbinbirinci"}, + {"test": 100010000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbininci"}, + {"test": 100010001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbinbirinci"}, + {"test": 100011000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbirbininci"}, + {"test": 100011001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbirbinbirinci"}, + {"test": 101011001, "lang": "tr", "to": "ordinal", "expected": u"yüzbirmilyononbirbinbirinci"}, + {"test": 101011010, "lang": "tr", "to": "ordinal", "expected": u"yüzbirmilyononbirbinonuncu"}, + {"test": 1101011010, "lang": "tr", "to": "ordinal", "expected": u"birmilyaryüzbirmilyononbirbinonuncu"}, + {"test": 101101011010, "lang": "tr", "to": "ordinal", "response": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, - {"number": 1000000000001, "lang": "tr", "to": "ordinal", "response": u"birtrilyonbirinci"}, - {"number": 1.2, "lang": "tr", "to": "ordinal", "response": u""}, - {"number": 1.3, "lang": "tr", "to": "ordinal", "response": u""}, - {"number": 3000, "lang": "tr", "to": "ordinal", "response": u"üçbininci"}, - {"number": 120000, "lang": "tr", "to": "ordinal", "response": u"yüzyirmibininci"}, - {"number": 1002002, "lang": "tr", "to": "ordinal", "response": u"birmilyonikibinikinci"}, - {"number": 1003000, "lang": "tr", "to": "ordinal", "response": u"birmilyonüçbininci"}, - {"number": 1200000, "lang": "tr", "to": "ordinal", "response": u"birmilyonikiyüzbininci"}, - {"number": 1, "lang": "tr", "to": "cardinal", "response": u"bir"}, - {"number": 2, "lang": "tr", "to": "cardinal", "response": u"iki"}, - {"number": 9, "lang": "tr", "to": "cardinal", "response": u"dokuz"}, - {"number": 10, "lang": "tr", "to": "cardinal", "response": u"on"}, - {"number": 11, "lang": "tr", "to": "cardinal", "response": u"onbir"}, - {"number": 44, "lang": "tr", "to": "cardinal", "response": u"kırkdört"}, - {"number": 100, "lang": "tr", "to": "cardinal", "response": u"yüz"}, - {"number": 101, "lang": "tr", "to": "cardinal", "response": u"yüzbir"}, - {"number": 103, "lang": "tr", "to": "cardinal", "response": u"yüzüç"}, - {"number": 110, "lang": "tr", "to": "cardinal", "response": u"yüzon"}, - {"number": 111, "lang": "tr", "to": "cardinal", "response": u"yüzonbir"}, - {"number": 1000, "lang": "tr", "to": "cardinal", "response": u"bin"}, - {"number": 1001, "lang": "tr", "to": "cardinal", "response": u"binbir"}, - {"number": 1010, "lang": "tr", "to": "cardinal", "response": u"binon"}, - {"number": 1011, "lang": "tr", "to": "cardinal", "response": u"binonbir"}, - {"number": 1100, "lang": "tr", "to": "cardinal", "response": u"binyüz"}, - {"number": 1110, "lang": "tr", "to": "cardinal", "response": u"binyüzon"}, - {"number": 2341, "lang": "tr", "to": "cardinal", "response": u"ikibinüçyüzkırkbir"}, - {"number": 10000, "lang": "tr", "to": "cardinal", "response": u"onbin"}, - {"number": 10010, "lang": "tr", "to": "cardinal", "response": u"onbinon"}, - {"number": 10100, "lang": "tr", "to": "cardinal", "response": u"onbinyüz"}, - {"number": 10110, "lang": "tr", "to": "cardinal", "response": u"onbinyüzon"}, - {"number": 11000, "lang": "tr", "to": "cardinal", "response": u"onbirbin"}, - {"number": 35000, "lang": "tr", "to": "cardinal", "response": u"otuzbeşbin"}, - {"number": 116331, "lang": "tr", "to": "cardinal", "response": u"yüzonaltıbinüçyüzotuzbir"}, - {"number": 116330, "lang": "tr", "to": "cardinal", "response": u"yüzonaltıbinüçyüzotuz"}, - {"number": 500000, "lang": "tr", "to": "cardinal", "response": u"beşyüzbin"}, - {"number": 501000, "lang": "tr", "to": "cardinal", "response": u"beşyüzbirbin"}, - {"number": 1000111, "lang": "tr", "to": "cardinal", "response": u"birmilyonyüzonbir"}, - {"number": 111000111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonyüzonbir"}, - {"number": 111001111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonbinyüzonbir"}, - {"number": 111111111, "lang": "tr", "to": "cardinal", "response": u"yüzonbirmilyonyüzonbirbinyüzonbir"}, - {"number": 100001000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbin"}, - {"number": 100001001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, - {"number": 100010000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbin"}, - {"number": 100010001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbinbir"}, - {"number": 100011000, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbirbin"}, - {"number": 100011001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyononbirbinbir"}, - {"number": 101011001, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyononbirbinbir"}, - {"number": 101011010, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyononbirbinon"}, - {"number": 1101011010, "lang": "tr", "to": "cardinal", "response": u"birmilyaryüzbirmilyononbirbinon"}, - {"number": 101101011010, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyaryüzbirmilyononbirbinon"}, - {"number": 100001001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, - {"number": 1000000000001, "lang": "tr", "to": "cardinal", "response": u"yüzmilyonbinbir"}, - {"number": 0.01, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülbir"}, - {"number": 0.21, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülyirmibir"}, - {"number": 0.1, "lang": "tr", "to": "cardinal", "response": u"sıfırvirgülon"}, - {"number": 1.01, "lang": "tr", "to": "cardinal", "response": u"birvirgülbir"}, - {"number": 1.1, "lang": "tr", "to": "cardinal", "response": u"birvirgülon"}, - {"number": 1.21, "lang": "tr", "to": "cardinal", "response": u"birvirgülyirmibir"}, - {"number": 101101011010.02, "lang": "tr", "to": "cardinal", + {"test": 1000000000001, "lang": "tr", "to": "ordinal", "expected": u"birtrilyonbirinci"}, + {"test": 1.2, "lang": "tr", "to": "ordinal", "expected": u""}, + {"test": 1.3, "lang": "tr", "to": "ordinal", "expected": u""}, + {"test": 3000, "lang": "tr", "to": "ordinal", "expected": u"üçbininci"}, + {"test": 120000, "lang": "tr", "to": "ordinal", "expected": u"yüzyirmibininci"}, + {"test": 1002002, "lang": "tr", "to": "ordinal", "expected": u"birmilyonikibinikinci"}, + {"test": 1003000, "lang": "tr", "to": "ordinal", "expected": u"birmilyonüçbininci"}, + {"test": 1200000, "lang": "tr", "to": "ordinal", "expected": u"birmilyonikiyüzbininci"}, + {"test": 1, "lang": "tr", "to": "cardinal", "expected": u"bir"}, + {"test": 2, "lang": "tr", "to": "cardinal", "expected": u"iki"}, + {"test": 9, "lang": "tr", "to": "cardinal", "expected": u"dokuz"}, + {"test": 10, "lang": "tr", "to": "cardinal", "expected": u"on"}, + {"test": 11, "lang": "tr", "to": "cardinal", "expected": u"onbir"}, + {"test": 44, "lang": "tr", "to": "cardinal", "expected": u"kırkdört"}, + {"test": 100, "lang": "tr", "to": "cardinal", "expected": u"yüz"}, + {"test": 101, "lang": "tr", "to": "cardinal", "expected": u"yüzbir"}, + {"test": 103, "lang": "tr", "to": "cardinal", "expected": u"yüzüç"}, + {"test": 110, "lang": "tr", "to": "cardinal", "expected": u"yüzon"}, + {"test": 111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbir"}, + {"test": 1000, "lang": "tr", "to": "cardinal", "expected": u"bin"}, + {"test": 1001, "lang": "tr", "to": "cardinal", "expected": u"binbir"}, + {"test": 1010, "lang": "tr", "to": "cardinal", "expected": u"binon"}, + {"test": 1011, "lang": "tr", "to": "cardinal", "expected": u"binonbir"}, + {"test": 1100, "lang": "tr", "to": "cardinal", "expected": u"binyüz"}, + {"test": 1110, "lang": "tr", "to": "cardinal", "expected": u"binyüzon"}, + {"test": 2341, "lang": "tr", "to": "cardinal", "expected": u"ikibinüçyüzkırkbir"}, + {"test": 10000, "lang": "tr", "to": "cardinal", "expected": u"onbin"}, + {"test": 10010, "lang": "tr", "to": "cardinal", "expected": u"onbinon"}, + {"test": 10100, "lang": "tr", "to": "cardinal", "expected": u"onbinyüz"}, + {"test": 10110, "lang": "tr", "to": "cardinal", "expected": u"onbinyüzon"}, + {"test": 11000, "lang": "tr", "to": "cardinal", "expected": u"onbirbin"}, + {"test": 35000, "lang": "tr", "to": "cardinal", "expected": u"otuzbeşbin"}, + {"test": 116331, "lang": "tr", "to": "cardinal", "expected": u"yüzonaltıbinüçyüzotuzbir"}, + {"test": 116330, "lang": "tr", "to": "cardinal", "expected": u"yüzonaltıbinüçyüzotuz"}, + {"test": 500000, "lang": "tr", "to": "cardinal", "expected": u"beşyüzbin"}, + {"test": 501000, "lang": "tr", "to": "cardinal", "expected": u"beşyüzbirbin"}, + {"test": 1000111, "lang": "tr", "to": "cardinal", "expected": u"birmilyonyüzonbir"}, + {"test": 111000111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonyüzonbir"}, + {"test": 111001111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonbinyüzonbir"}, + {"test": 111111111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonyüzonbirbinyüzonbir"}, + {"test": 100001000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbin"}, + {"test": 100001001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"test": 100010000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbin"}, + {"test": 100010001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbinbir"}, + {"test": 100011000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbirbin"}, + {"test": 100011001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbirbinbir"}, + {"test": 101011001, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyononbirbinbir"}, + {"test": 101011010, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyononbirbinon"}, + {"test": 1101011010, "lang": "tr", "to": "cardinal", "expected": u"birmilyaryüzbirmilyononbirbinon"}, + {"test": 101101011010, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyaryüzbirmilyononbirbinon"}, + {"test": 100001001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"test": 1000000000001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"test": 0.01, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülbir"}, + {"test": 0.21, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülyirmibir"}, + {"test": 0.1, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülon"}, + {"test": 1.01, "lang": "tr", "to": "cardinal", "expected": u"birvirgülbir"}, + {"test": 1.1, "lang": "tr", "to": "cardinal", "expected": u"birvirgülon"}, + {"test": 1.21, "lang": "tr", "to": "cardinal", "expected": u"birvirgülyirmibir"}, + {"test": 101101011010.02, "lang": "tr", "to": "cardinal", "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, - {"number": 101101011010.2, "lang": "tr", "to": "cardinal", - "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"}, + {"test": 101101011010.2, "lang": "tr", "to": "cardinal", + "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"} ] for casedata in testcases: - self.assertEqual(num2words(casedata.number, lang=casedata.lang, to=casedata.to), casedata.response) + self.assertEqual(num2words(casedata.test, lang=casedata.lang, to=casedata.to), casedata.expected) From 6a4e9550498a6684ab476b571de264fd3397f12c Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 19:02:02 +0300 Subject: [PATCH 059/340] updated tests --- tests/test_tr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 9737d632..e7158756 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -141,4 +141,5 @@ def test_tr(self): ] for casedata in testcases: - self.assertEqual(num2words(casedata.test, lang=casedata.lang, to=casedata.to), casedata.expected) + self.assertEqual(num2words(casedata["test"], lang=casedata["lang"], to=casedata["to"]), + casedata["expected"]) From fe0bc1adbd19e25875bb9feb6ea8c85ab88c6e66 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 19:06:36 +0300 Subject: [PATCH 060/340] updated tests --- tests/test_tr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index e7158756..0295fb2d 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -75,7 +75,7 @@ def test_tr(self): {"test": 101011010, "lang": "tr", "to": "ordinal", "expected": u"yüzbirmilyononbirbinonuncu"}, {"test": 1101011010, "lang": "tr", "to": "ordinal", "expected": u"birmilyaryüzbirmilyononbirbinonuncu"}, {"test": 101101011010, "lang": "tr", "to": "ordinal", - "response": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, {"test": 1000000000001, "lang": "tr", "to": "ordinal", "expected": u"birtrilyonbirinci"}, {"test": 1.2, "lang": "tr", "to": "ordinal", "expected": u""}, {"test": 1.3, "lang": "tr", "to": "ordinal", "expected": u""}, @@ -135,9 +135,9 @@ def test_tr(self): {"test": 1.1, "lang": "tr", "to": "cardinal", "expected": u"birvirgülon"}, {"test": 1.21, "lang": "tr", "to": "cardinal", "expected": u"birvirgülyirmibir"}, {"test": 101101011010.02, "lang": "tr", "to": "cardinal", - "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, {"test": 101101011010.2, "lang": "tr", "to": "cardinal", - "response": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"} + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"} ] for casedata in testcases: From 3da9fd87058c5e41d3966bb0156f3a77a15c4282 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 19:08:49 +0300 Subject: [PATCH 061/340] updated tests --- tests/test_tr.py | 226 +++++++++++++++++++++++------------------------ 1 file changed, 111 insertions(+), 115 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 0295fb2d..b6bae54f 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -24,122 +24,118 @@ class Num2WordsTRTest(TestCase): def test_tr(self): # ref https://github.com/savoirfairelinux/num2words/issues/8 - + testlang = "tr" testcases = [ - {"test": 0, "lang": "tr", "to": "currency", "expected": u"bedelsiz"}, - {"test": 1.1, "lang": "tr", "to": "currency", "expected": u"birliraonkuruş"}, - {"test": 2000, "lang": "tr", "to": "currency", "expected": u"ikibinlira"}, - {"test": 110000, "lang": "tr", "to": "currency", "expected": u"yüzonbinlira"}, - {"test": 1002000, "lang": "tr", "to": "currency", "expected": u"birmilyonikibinlira"}, - {"test": 1002001, "lang": "tr", "to": "currency", "expected": u"birmilyonikibinbirlira"}, - {"test": 1100000, "lang": "tr", "to": "currency", "expected": u"birmilyonyüzbinlira"}, - {"test": 1, "lang": "tr", "to": "ordinal", "expected": u"birinci"}, - {"test": 2, "lang": "tr", "to": "ordinal", "expected": u"ikinci"}, - {"test": 9, "lang": "tr", "to": "ordinal", "expected": u"dokuzuncu"}, - {"test": 10, "lang": "tr", "to": "ordinal", "expected": u"onuncu"}, - {"test": 11, "lang": "tr", "to": "ordinal", "expected": u"onbirinci"}, - {"test": 44, "lang": "tr", "to": "ordinal", "expected": u"kırkdördüncü"}, - {"test": 100, "lang": "tr", "to": "ordinal", "expected": u"yüzüncü"}, - {"test": 101, "lang": "tr", "to": "ordinal", "expected": u"yüzbirinci"}, - {"test": 103, "lang": "tr", "to": "ordinal", "expected": u"yüzüçüncü"}, - {"test": 110, "lang": "tr", "to": "ordinal", "expected": u"yüzonuncu"}, - {"test": 111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirinci"}, - {"test": 1000, "lang": "tr", "to": "ordinal", "expected": u"bininci"}, - {"test": 1001, "lang": "tr", "to": "ordinal", "expected": u"binbirinci"}, - {"test": 1010, "lang": "tr", "to": "ordinal", "expected": u"binonuncu"}, - {"test": 1011, "lang": "tr", "to": "ordinal", "expected": u"binonbirinci"}, - {"test": 1100, "lang": "tr", "to": "ordinal", "expected": u"binyüzüncü"}, - {"test": 1110, "lang": "tr", "to": "ordinal", "expected": u"binyüzonuncu"}, - {"test": 2341, "lang": "tr", "to": "ordinal", "expected": u"ikibinüçyüzkırkbirinci"}, - {"test": 10000, "lang": "tr", "to": "ordinal", "expected": u"onbininci"}, - {"test": 10010, "lang": "tr", "to": "ordinal", "expected": u"onbinonuncu"}, - {"test": 10100, "lang": "tr", "to": "ordinal", "expected": u"onbinyüzüncü"}, - {"test": 10110, "lang": "tr", "to": "ordinal", "expected": u"onbinyüzonuncu"}, - {"test": 11000, "lang": "tr", "to": "ordinal", "expected": u"onbirbininci"}, - {"test": 35000, "lang": "tr", "to": "ordinal", "expected": u"otuzbeşbininci"}, - {"test": 116331, "lang": "tr", "to": "ordinal", "expected": u"yüzonaltıbinüçyüzotuzbirinci"}, - {"test": 116330, "lang": "tr", "to": "ordinal", "expected": u"yüzonaltıbinüçyüzotuzuncu"}, - {"test": 100000, "lang": "tr", "to": "ordinal", "expected": u"yüzbininci"}, - {"test": 501000, "lang": "tr", "to": "ordinal", "expected": u"beşyüzbirbininci"}, - {"test": 1000111, "lang": "tr", "to": "ordinal", "expected": u"birmilyonyüzonbirinci"}, - {"test": 111000111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonyüzonbirinci"}, - {"test": 111001111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonbinyüzonbirinci"}, - {"test": 111111111, "lang": "tr", "to": "ordinal", "expected": u"yüzonbirmilyonyüzonbirbinyüzonbirinci"}, - {"test": 100001000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyonbininci"}, - {"test": 100001001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyonbinbirinci"}, - {"test": 100010000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbininci"}, - {"test": 100010001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbinbirinci"}, - {"test": 100011000, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbirbininci"}, - {"test": 100011001, "lang": "tr", "to": "ordinal", "expected": u"yüzmilyononbirbinbirinci"}, - {"test": 101011001, "lang": "tr", "to": "ordinal", "expected": u"yüzbirmilyononbirbinbirinci"}, - {"test": 101011010, "lang": "tr", "to": "ordinal", "expected": u"yüzbirmilyononbirbinonuncu"}, - {"test": 1101011010, "lang": "tr", "to": "ordinal", "expected": u"birmilyaryüzbirmilyononbirbinonuncu"}, - {"test": 101101011010, "lang": "tr", "to": "ordinal", - "expected": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, - {"test": 1000000000001, "lang": "tr", "to": "ordinal", "expected": u"birtrilyonbirinci"}, - {"test": 1.2, "lang": "tr", "to": "ordinal", "expected": u""}, - {"test": 1.3, "lang": "tr", "to": "ordinal", "expected": u""}, - {"test": 3000, "lang": "tr", "to": "ordinal", "expected": u"üçbininci"}, - {"test": 120000, "lang": "tr", "to": "ordinal", "expected": u"yüzyirmibininci"}, - {"test": 1002002, "lang": "tr", "to": "ordinal", "expected": u"birmilyonikibinikinci"}, - {"test": 1003000, "lang": "tr", "to": "ordinal", "expected": u"birmilyonüçbininci"}, - {"test": 1200000, "lang": "tr", "to": "ordinal", "expected": u"birmilyonikiyüzbininci"}, - {"test": 1, "lang": "tr", "to": "cardinal", "expected": u"bir"}, - {"test": 2, "lang": "tr", "to": "cardinal", "expected": u"iki"}, - {"test": 9, "lang": "tr", "to": "cardinal", "expected": u"dokuz"}, - {"test": 10, "lang": "tr", "to": "cardinal", "expected": u"on"}, - {"test": 11, "lang": "tr", "to": "cardinal", "expected": u"onbir"}, - {"test": 44, "lang": "tr", "to": "cardinal", "expected": u"kırkdört"}, - {"test": 100, "lang": "tr", "to": "cardinal", "expected": u"yüz"}, - {"test": 101, "lang": "tr", "to": "cardinal", "expected": u"yüzbir"}, - {"test": 103, "lang": "tr", "to": "cardinal", "expected": u"yüzüç"}, - {"test": 110, "lang": "tr", "to": "cardinal", "expected": u"yüzon"}, - {"test": 111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbir"}, - {"test": 1000, "lang": "tr", "to": "cardinal", "expected": u"bin"}, - {"test": 1001, "lang": "tr", "to": "cardinal", "expected": u"binbir"}, - {"test": 1010, "lang": "tr", "to": "cardinal", "expected": u"binon"}, - {"test": 1011, "lang": "tr", "to": "cardinal", "expected": u"binonbir"}, - {"test": 1100, "lang": "tr", "to": "cardinal", "expected": u"binyüz"}, - {"test": 1110, "lang": "tr", "to": "cardinal", "expected": u"binyüzon"}, - {"test": 2341, "lang": "tr", "to": "cardinal", "expected": u"ikibinüçyüzkırkbir"}, - {"test": 10000, "lang": "tr", "to": "cardinal", "expected": u"onbin"}, - {"test": 10010, "lang": "tr", "to": "cardinal", "expected": u"onbinon"}, - {"test": 10100, "lang": "tr", "to": "cardinal", "expected": u"onbinyüz"}, - {"test": 10110, "lang": "tr", "to": "cardinal", "expected": u"onbinyüzon"}, - {"test": 11000, "lang": "tr", "to": "cardinal", "expected": u"onbirbin"}, - {"test": 35000, "lang": "tr", "to": "cardinal", "expected": u"otuzbeşbin"}, - {"test": 116331, "lang": "tr", "to": "cardinal", "expected": u"yüzonaltıbinüçyüzotuzbir"}, - {"test": 116330, "lang": "tr", "to": "cardinal", "expected": u"yüzonaltıbinüçyüzotuz"}, - {"test": 500000, "lang": "tr", "to": "cardinal", "expected": u"beşyüzbin"}, - {"test": 501000, "lang": "tr", "to": "cardinal", "expected": u"beşyüzbirbin"}, - {"test": 1000111, "lang": "tr", "to": "cardinal", "expected": u"birmilyonyüzonbir"}, - {"test": 111000111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonyüzonbir"}, - {"test": 111001111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonbinyüzonbir"}, - {"test": 111111111, "lang": "tr", "to": "cardinal", "expected": u"yüzonbirmilyonyüzonbirbinyüzonbir"}, - {"test": 100001000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbin"}, - {"test": 100001001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, - {"test": 100010000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbin"}, - {"test": 100010001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbinbir"}, - {"test": 100011000, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbirbin"}, - {"test": 100011001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyononbirbinbir"}, - {"test": 101011001, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyononbirbinbir"}, - {"test": 101011010, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyononbirbinon"}, - {"test": 1101011010, "lang": "tr", "to": "cardinal", "expected": u"birmilyaryüzbirmilyononbirbinon"}, - {"test": 101101011010, "lang": "tr", "to": "cardinal", "expected": u"yüzbirmilyaryüzbirmilyononbirbinon"}, - {"test": 100001001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, - {"test": 1000000000001, "lang": "tr", "to": "cardinal", "expected": u"yüzmilyonbinbir"}, - {"test": 0.01, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülbir"}, - {"test": 0.21, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülyirmibir"}, - {"test": 0.1, "lang": "tr", "to": "cardinal", "expected": u"sıfırvirgülon"}, - {"test": 1.01, "lang": "tr", "to": "cardinal", "expected": u"birvirgülbir"}, - {"test": 1.1, "lang": "tr", "to": "cardinal", "expected": u"birvirgülon"}, - {"test": 1.21, "lang": "tr", "to": "cardinal", "expected": u"birvirgülyirmibir"}, - {"test": 101101011010.02, "lang": "tr", "to": "cardinal", - "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, - {"test": 101101011010.2, "lang": "tr", "to": "cardinal", - "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"} + {"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": 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": 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": 100001001, "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"test": 1000000000001, "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"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"} ] for casedata in testcases: - self.assertEqual(num2words(casedata["test"], lang=casedata["lang"], to=casedata["to"]), - casedata["expected"]) + self.assertEqual(num2words(casedata["test"], lang=testlang, to=casedata["to"]), casedata["expected"]) From 39ef298626a3b410e0b703d59af5d9c749b00ac2 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 19:13:41 +0300 Subject: [PATCH 062/340] updated tests --- tests/test_tr.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index b6bae54f..c29ecb32 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -125,8 +125,7 @@ def test_tr(self): {"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": 100001001, "to": "cardinal", "expected": u"yüzmilyonbinbir"}, - {"test": 1000000000001, "to": "cardinal", "expected": u"yüzmilyonbinbir"}, + {"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"}, From 02362578768f8005722b8b00b60cf7613da3d2c6 Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 19:49:39 +0300 Subject: [PATCH 063/340] updated tests --- tests/test_tr.py | 144 +++++++++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 48 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index c29ecb32..564493ab 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -30,9 +30,12 @@ def test_tr(self): {"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": 1002000, "to": "currency", + "expected": u"birmilyonikibinlira"}, + {"test": 1002001, "to": "currency", + "expected": u"birmilyonikibinbirlira"}, + {"test": 1100000, "to": "currency", + "expected": u"birmilyonyüzbinlira"}, {"test": 1, "to": "ordinal", "expected": u"birinci"}, {"test": 2, "to": "ordinal", "expected": u"ikinci"}, {"test": 9, "to": "ordinal", "expected": u"dokuzuncu"}, @@ -50,39 +53,61 @@ def test_tr(self): {"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": 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": 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": 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": 1002002, "to": "ordinal", + "expected": u"birmilyonikibinikinci"}, + {"test": 1003000, "to": "ordinal", + "expected": u"birmilyonüçbininci"}, + {"test": 1200000, "to": "ordinal", + "expected": u"birmilyonikiyüzbininci"}, {"test": 1, "to": "cardinal", "expected": u"bir"}, {"test": 2, "to": "cardinal", "expected": u"iki"}, {"test": 9, "to": "cardinal", "expected": u"dokuz"}, @@ -100,41 +125,64 @@ def test_tr(self): {"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": 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": 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": 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.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": 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"} ] for casedata in testcases: - self.assertEqual(num2words(casedata["test"], lang=testlang, to=casedata["to"]), casedata["expected"]) + self.assertEqual(num2words(casedata["test"], lang=testlang, + to=casedata["to"]), casedata["expected"]) From 234e02dd54dc44414d65a325d7e9d5f5a387204d Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 13 Dec 2019 20:18:59 +0300 Subject: [PATCH 064/340] updated tests --- tests/test_tr.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 564493ab..a6fc968a 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -184,5 +184,8 @@ def test_tr(self): ] for casedata in testcases: - self.assertEqual(num2words(casedata["test"], lang=testlang, - to=casedata["to"]), casedata["expected"]) + self.assertEqual( + num2words(casedata["test"], + lang=testlang, + to=casedata["to"]), + casedata["expected"]) From d576817c7fb281e4a232c9a84a88bdc42cb58f7a Mon Sep 17 00:00:00 2001 From: Olzhas Date: Tue, 7 Jan 2020 00:59:39 +0600 Subject: [PATCH 065/340] Initial kazakh implementation --- num2words/__init__.py | 7 ++- num2words/lang_KZ.py | 134 ++++++++++++++++++++++++++++++++++++++++++ tests/test_kz.py | 45 ++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 num2words/lang_KZ.py create mode 100644 tests/test_kz.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 37109349..b5136425 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -20,9 +20,9 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, - lang_JA, lang_KN, lang_KO, lang_LT, lang_LV, lang_NL, lang_NO, - lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, - lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) + lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, + lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, + lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -43,6 +43,7 @@ '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(), diff --git a/num2words/lang_KZ.py b/num2words/lang_KZ.py new file mode 100644 index 00000000..73488a6d --- /dev/null +++ b/num2words/lang_KZ.py @@ -0,0 +1,134 @@ +# -*- 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('.') + 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, 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/tests/test_kz.py b/tests/test_kz.py new file mode 100644 index 00000000..0ed401e1 --- /dev/null +++ b/tests/test_kz.py @@ -0,0 +1,45 @@ +# -*- 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(84932, lang='kz'), 'сексен төрт мың тоғыз жүз отыз екі') + + def test_to_cardinal_floats(self): + self.assertEqual(num2words(100.67, 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'), + 'жиырма бес теңге, жиырма төрт тиын' + ) From d7742442c673b566cc5905ed90dca9f75eb22045 Mon Sep 17 00:00:00 2001 From: Olzhas Date: Sat, 11 Jan 2020 00:31:46 +0600 Subject: [PATCH 066/340] Updated kz tests --- tests/test_kz.py | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/tests/test_kz.py b/tests/test_kz.py index 0ed401e1..4d632318 100644 --- a/tests/test_kz.py +++ b/tests/test_kz.py @@ -25,21 +25,41 @@ 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(84932, lang='kz'), 'сексен төрт мың тоғыз жүз отыз екі') + 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(84932, lang="kz"), "сексен төрт мың тоғыз жүз отыз екі" + ) def test_to_cardinal_floats(self): - self.assertEqual(num2words(100.67, lang='kz'), 'жүз бүтін алпыс жеті') + self.assertEqual(num2words(100.67, lang="kz"), "жүз бүтін алпыс жеті") + self.assertEqual(num2words(0.7, lang="kz"), "нөл бүтін жеті") + self.assertEqual(num2words(1.73, lang="kz"), "бір бүтін жетпіс үш") def test_to_ordinal(self): with self.assertRaises(NotImplementedError): - num2words(1, lang='kz', to='ordinal') + num2words(1, lang="kz", to="ordinal") def test_to_currency(self): self.assertEqual( - num2words(25.24, lang='kz', to='currency', currency='KZT'), - 'жиырма бес теңге, жиырма төрт тиын' + 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"), + "тоғыз жүз сексен жеті миллион алты жүз елу төрт мың үш жүз жиырма бір теңге, он екі тиын", ) From 3bb4ab120a3b96d3739944cd44b5a1b97111b5ea Mon Sep 17 00:00:00 2001 From: Olzhas Date: Sat, 11 Jan 2020 00:42:55 +0600 Subject: [PATCH 067/340] Added kz tests for negative numbers and zero in chunks --- tests/test_kz.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_kz.py b/tests/test_kz.py index 4d632318..10260f4a 100644 --- a/tests/test_kz.py +++ b/tests/test_kz.py @@ -29,6 +29,10 @@ def test_to_cardinal(self): 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"), "сексен төрт мың тоғыз жүз отыз екі" ) From c2abbbec5994a0e9a0c49754c99569f4db276b9a Mon Sep 17 00:00:00 2001 From: Olzhas Date: Sat, 11 Jan 2020 13:11:39 +0600 Subject: [PATCH 068/340] Linted KZ modules --- num2words/lang_KZ.py | 2 -- tests/test_kz.py | 8 ++++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/num2words/lang_KZ.py b/num2words/lang_KZ.py index 73488a6d..2486325d 100644 --- a/num2words/lang_KZ.py +++ b/num2words/lang_KZ.py @@ -15,13 +15,11 @@ # 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 = { diff --git a/tests/test_kz.py b/tests/test_kz.py index 10260f4a..68f71f2f 100644 --- a/tests/test_kz.py +++ b/tests/test_kz.py @@ -28,7 +28,10 @@ def test_to_cardinal(self): 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(2869, lang="kz"), + "екі мың сегіз жүз алпыс тоғыз" + ) self.assertEqual( num2words(-789000125, lang="kz"), "минус жеті жүз сексен тоғыз миллион жүз жиырма бес", @@ -65,5 +68,6 @@ def test_to_currency(self): ) self.assertEqual( num2words(987654321.123, lang="kz", to="currency", currency="KZT"), - "тоғыз жүз сексен жеті миллион алты жүз елу төрт мың үш жүз жиырма бір теңге, он екі тиын", + "тоғыз жүз сексен жеті миллион алты жүз елу төрт мың " + "үш жүз жиырма бір теңге, он екі тиын", ) From 7c924fe8efd8532fad87aa5452c12397633803f6 Mon Sep 17 00:00:00 2001 From: Olzhas Date: Sun, 12 Jan 2020 13:22:55 +0600 Subject: [PATCH 069/340] Added kazakh lang to README --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 6c7bcecf..668ff358 100644 --- a/README.rst +++ b/README.rst @@ -97,6 +97,7 @@ Besides the numerical argument, there are two main optional arguments. * ``ja`` (Japanese) * ``kn`` (Kannada) * ``ko`` (Korean) +* ``kz`` (Kazakh) * ``lt`` (Lithuanian) * ``lv`` (Latvian) * ``no`` (Norwegian) From ebdb52e55fc0dafe223b39a653e8a6d02ca6526a Mon Sep 17 00:00:00 2001 From: Sarah Beranek <4508867+sarahberanek@users.noreply.github.com> Date: Wed, 15 Jan 2020 15:44:07 +0100 Subject: [PATCH 070/340] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 668ff358..9914f1c1 100644 --- a/README.rst +++ b/README.rst @@ -108,7 +108,7 @@ Besides the numerical argument, there are two main optional arguments. * ``sr`` (Serbian) * ``ro`` (Romanian) * ``ru`` (Russian) -* ``sl`` (Slovene) +* ``te`` (Telugu) * ``tr`` (Turkish) * ``th`` (Thai) * ``vi`` (Vietnamese) From 4dab316025fe1b36e621b8de4daba2d2ced6809b Mon Sep 17 00:00:00 2001 From: Daniel Marai Date: Tue, 28 Jan 2020 17:17:16 +0100 Subject: [PATCH 071/340] Added support for Hungarian language --- README.rst | 1 + num2words/__init__.py | 12 ++- num2words/lang_EU.py | 2 + num2words/lang_HU.py | 165 ++++++++++++++++++++++++++++++++ tests/test_hu.py | 213 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 388 insertions(+), 5 deletions(-) create mode 100644 num2words/lang_HU.py create mode 100644 tests/test_hu.py diff --git a/README.rst b/README.rst index 9914f1c1..db64202b 100644 --- a/README.rst +++ b/README.rst @@ -92,6 +92,7 @@ Besides the numerical argument, there are two main optional arguments. * ``fr_BE`` (French - Belgium) * ``fr_DZ`` (French - Algeria) * ``he`` (Hebrew) +* ``hu`` (Hungarian) * ``id`` (Indonesian) * ``it`` (Italian) * ``ja`` (Japanese) diff --git a/num2words/__init__.py b/num2words/__init__.py index b5136425..bb18ea42 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -19,10 +19,11 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, - lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, - lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, - lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) + lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, + lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, + lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, + lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, + lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -62,7 +63,8 @@ 'tr': lang_TR.Num2Word_TR(), 'nl': lang_NL.Num2Word_NL(), 'uk': lang_UK.Num2Word_UK(), - 'te': lang_TE.Num2Word_TE() + 'te': lang_TE.Num2Word_TE(), + 'hu': lang_HU.Num2Word_HU() } diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 748f9356..3bc7c809 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -43,6 +43,7 @@ class Num2Word_EU(Num2Word_Base): 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'INR': (('rupee', 'rupees'), ('paisa', 'paise')) + 'HUF': (('forint', 'forint'), ('fillér', 'fillér')) } CURRENCY_ADJECTIVES = { @@ -55,6 +56,7 @@ class Num2Word_EU(Num2Word_Base): 'MXN': 'Mexican', 'RON': 'Romanian', 'INR': 'Indian', + 'HUF': 'Hungarian' } GIGA_SUFFIX = "illiard" 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/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ó') From fb7ac2108959bed6d29c785c9558eef4b3c50980 Mon Sep 17 00:00:00 2001 From: Daniel Marai Date: Tue, 28 Jan 2020 17:24:20 +0100 Subject: [PATCH 072/340] Fixed comma error --- num2words/lang_EU.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 3bc7c809..09d39c15 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -42,7 +42,7 @@ class Num2Word_EU(Num2Word_Base): 'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')), 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), - 'INR': (('rupee', 'rupees'), ('paisa', 'paise')) + 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), 'HUF': (('forint', 'forint'), ('fillér', 'fillér')) } From e5bed36054b4cb99469b1d9646ae97eb593cf996 Mon Sep 17 00:00:00 2001 From: Daniel Marai Date: Tue, 28 Jan 2020 17:26:26 +0100 Subject: [PATCH 073/340] Removed unnecessary whitespaces --- num2words/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index bb18ea42..931d28af 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -20,9 +20,9 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, + lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, + lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, + lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { From 47a3cac323bf9290a28ec1f28b5c5fb9dcf1318c Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Mon, 21 Sep 2020 18:53:47 +0200 Subject: [PATCH 074/340] Fix zeroth in Dutch to nulde fixing #325 --- num2words/lang_NL.py | 5 ++++- tests/test_nl.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/num2words/lang_NL.py b/num2words/lang_NL.py index ac4d4051..8725714c 100644 --- a/num2words/lang_NL.py +++ b/num2words/lang_NL.py @@ -76,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", diff --git a/tests/test_nl.py b/tests/test_nl.py index e72b43bf..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" From a6cae07703045c251fc8f608aef55ba706896499 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:02:49 +0300 Subject: [PATCH 075/340] fix pluralize --- num2words/lang_HE.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 34b2ec8a..2b96dc1b 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -81,11 +81,7 @@ def pluralize(n, forms): - # gettext implementation: - # (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2) - - form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2 - + form = 1 if n == 0 else 0 if n == 1 else 1 return forms[form] @@ -151,6 +147,9 @@ def to_cardinal(self, number): def to_ordinal(self, number): raise NotImplementedError() + def pluralize(self, n, forms): + return pluralize(n, forms) + if __name__ == '__main__': yo = Num2Word_HE() From 92a0915508514983a8f1388d6acf062f593ac8e4 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:03:43 +0300 Subject: [PATCH 076/340] implement currency for HE --- num2words/lang_HE.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 2b96dc1b..f9871925 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -136,11 +136,13 @@ def n2w(n): return int2word(int(n)) -def to_currency(n, currency='EUR', cents=True, separator=','): - raise NotImplementedError() - - class Num2Word_HE(Num2Word_Base): + CURRENCY_FORMS = { + 'NIS': (('שקל', 'שקלים'), ('אגורה', 'אגורות')), + 'EUR': (('אירו', 'אירו'), ('סנט', 'סנט')), + 'USD': (('דולר', 'דולרים'), ('סנט', 'סנט')), + } + def to_cardinal(self, number): return n2w(number) @@ -150,6 +152,14 @@ def to_ordinal(self, number): def pluralize(self, n, forms): return pluralize(n, forms) + def to_currency(self, val, currency='NIS', cents=True, separator=' ו', + adjective=False): + result = super(Num2Word_HE, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + # In Hebrew the separator is along with the following word + return result.replace(" ו ", " ו") + if __name__ == '__main__': yo = Num2Word_HE() From 6ea1a3da713906117e0660bd5dd68a5cad392053 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:03:57 +0300 Subject: [PATCH 077/340] add unit tests --- tests/test_he.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_he.py b/tests/test_he.py index 206d7cc5..5a17694e 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -20,6 +20,7 @@ from unittest import TestCase from num2words import num2words +from num2words.lang_HE import Num2Word_HE class Num2WordsHETest(TestCase): @@ -71,3 +72,39 @@ def test_1000_to_9999(self): self.assertEqual( num2words(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים' ) + + def test_pluralize(self): + n = Num2Word_HE() + cr1, cr2 = n.CURRENCY_FORMS['NIS'] + self.assertEqual(n.pluralize(1, cr1), 'שקל') + self.assertEqual(n.pluralize(2, cr1), 'שקלים') + self.assertEqual(n.pluralize(1, cr2), 'אגורה') + self.assertEqual(n.pluralize(2, cr2), 'אגורות') + + cr1, cr2 = n.CURRENCY_FORMS['USD'] + self.assertEqual(n.pluralize(1, cr1), 'דולר') + self.assertEqual(n.pluralize(2, cr1), 'דולרים') + self.assertEqual(n.pluralize(1, cr2), 'סנט') + self.assertEqual(n.pluralize(2, cr2), 'סנט') + + def test_currency_(self): + n = Num2Word_HE() + self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') + self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') + self.assertEqual(n.to_currency(100.50 ,currency='NIS'), 'מאה שקלים וחמישים אגורות') + + def test_to_cardinal(self): + n = Num2Word_HE() + self.assertEqual(n.to_cardinal(1500), u'אלף וחמש מאות') + + +class Num2WordsHETestNotImplementedMethofs(TestCase): + n = Num2Word_HE() + + def test_to_ordinal(self): + with self.assertRaises(NotImplementedError): + self.n.to_ordinal('1') + + def test_large_number(self): + with self.assertRaises(NotImplementedError): + num2words(2000000, lang="he") From c95fe6260b1a5fd3f40cb4ac5f10557315d1507f Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:14:21 +0300 Subject: [PATCH 078/340] typo --- tests/test_he.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_he.py b/tests/test_he.py index 5a17694e..688bbf04 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -87,7 +87,7 @@ def test_pluralize(self): self.assertEqual(n.pluralize(1, cr2), 'סנט') self.assertEqual(n.pluralize(2, cr2), 'סנט') - def test_currency_(self): + def test_to_currency(self): n = Num2Word_HE() self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') From 895af7dccfad73e51f8ea66b6b7577279cc51f75 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 7 Dec 2020 14:24:51 +0100 Subject: [PATCH 079/340] added swedish language including test cases --- num2words/__init__.py | 3 +- num2words/lang_SV.py | 113 ++++++++++++++++++++++++++++++++++++++++++ tests/test_sv.py | 46 +++++++++++++++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_SV.py create mode 100644 tests/test_sv.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 931d28af..6d40774c 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,7 +22,7 @@ lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { @@ -52,6 +52,7 @@ 'ru': lang_RU.Num2Word_RU(), '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(), diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py new file mode 100644 index 00000000..215c196b --- /dev/null +++ b/num2words/lang_SV.py @@ -0,0 +1,113 @@ +# -*- 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(" ") + lastwords = outwords[-1].split("-") + lastword = lastwords[-1].lower() + try: + lastword = self.ords[lastword] + except KeyError: + if lastword[-2:] == "tio": + lastword = lastword + "onde" + else: + lastword += "de" + lastwords[-1] = self.title(lastword) + outwords[-1] = "".join(lastwords) + return " ".join(outwords) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) + + def to_year(self, val, longval=True): + if not (val // 100) % 10: + return self.to_cardinal(val) + return self.to_splitnum(val, hightxt="hundra", jointxt="och", + longval=longval) + + def to_currency(self, val, longval=True): + return self.to_splitnum(val, hightxt="krone/r", lowtxt="öre/n", + jointxt="och", longval=longval, cents=True) diff --git a/tests/test_sv.py b/tests/test_sv.py new file mode 100644 index 00000000..fa3d48da --- /dev/null +++ b/tests/test_sv.py @@ -0,0 +1,46 @@ +# 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): + pass + self.assertEqual(num2words(1, to="ordinal", lang="sv"), "första") + self.assertEqual(num2words(5, to="ordinal", lang="sv"), "femte") + self.assertEqual(num2words(32, to="ordinal", lang="sv"), "trettioandra") + + + 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(2, to="cardinal", lang="sv"), "två") + self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem") + self.assertEqual(num2words(8, to="cardinal", lang="sv"), "åtta") + self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton") + self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem") + self.assertEqual(num2words(1245, to="cardinal", lang="sv"), "etttusen tvåhundraförtiofem") + self.assertEqual(num2words(4235, to="cardinal", lang="sv"), "fyratusen tvåhundratrettiofem") + self.assertEqual(num2words(1004135, to="cardinal", lang="sv"), "en miljon fyratusen etthundratrettiofem") + self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") + self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") + self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två fem") From e88f3d75e35bda8a5d7386fe231c72290258d202 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 7 Dec 2020 16:24:58 +0100 Subject: [PATCH 080/340] added correct ordinal handling and more test cases --- num2words/lang_SV.py | 22 +++++++++++++--------- tests/test_sv.py | 6 +++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 215c196b..12ba9ae9 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -85,17 +85,21 @@ def merge(self, lpair, rpair): def to_ordinal(self, value): self.verify_ordinal(value) outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") - lastword = lastwords[-1].lower() + lastword = outwords[-1] + # lastword = lastwords[-1].lower() + ending_length = 0 try: - lastword = self.ords[lastword] - except KeyError: - if lastword[-2:] == "tio": - lastword = lastword + "onde" - else: + lastword_ending = self.ords[lastword[-4:]] + ending_length = 4 + except: + try: + lastword_ending = self.ords[lastword[-3:]] + ending_length = 3 + except KeyError: lastword += "de" - lastwords[-1] = self.title(lastword) - outwords[-1] = "".join(lastwords) + 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): diff --git a/tests/test_sv.py b/tests/test_sv.py index fa3d48da..e4ce4662 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -24,11 +24,11 @@ class Num2WordsSVTest(TestCase): def test_ordinal(self): - pass + 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(32, to="ordinal", lang="sv"), "trettioandra") - + self.assertEqual(num2words(10, to="ordinal", lang="sv"), "tionde") def test_cardinal(self): self.assertEqual(num2words(0, to="cardinal", lang="sv"), "noll") From f65df3fc613b45a6987fa966fb99ffcc89efe58e Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Wed, 16 Dec 2020 21:11:52 +0330 Subject: [PATCH 081/340] add basic farsi support --- README.rst | 1 + num2words/__init__.py | 3 +- num2words/lang_FA.py | 165 ++++++++++++++++++++++++++++++++++++++++++ tests/test_fa.py | 85 ++++++++++++++++++++++ 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_FA.py create mode 100644 tests/test_fa.py diff --git a/README.rst b/README.rst index db64202b..c8524c58 100644 --- a/README.rst +++ b/README.rst @@ -86,6 +86,7 @@ Besides the numerical argument, there are two main optional arguments. * ``es_CO`` (Spanish - Colombia) * ``es_VE`` (Spanish - Venezuela) * ``eu`` (EURO) +* ``fa`` (Farsi) * ``fi`` (Finnish) * ``fr`` (French) * ``fr_CH`` (French - Switzerland) diff --git a/num2words/__init__.py b/num2words/__init__.py index 931d28af..0b85ec7f 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, @@ -30,6 +30,7 @@ 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), + '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(), diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py new file mode 100644 index 00000000..9e232a79 --- /dev/null +++ b/num2words/lang_FA.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. +# Copyright (c) 2018, Abdullah Alhazmy, Alhazmy13. 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 + +import re +from decimal import Decimal +from math import floor + +farsiOnes = [ + "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", + "نه", + "ده", + "یازده", + "دوازده", + "سیزده", + "چهارده", + "پونزده", + "شونزده", + "هیفده", + "هیجده", + "نوزده", +] + +farsiTens = [ + "", + "ده", + "بیست", + "سی", + "چهل", + "پنجاه", + "شصت", + "هفتاد", + "هشتاد", + "نود", +] + +farsiHundreds = [ + "", + "صد", + "دویست", + "سیصد", + "چهارصد", + "پانصد", + "ششصد", + "هفتصد", + "هشتصد", + "نهصد", +] + +farsiBig = [ + '', + ' هزار', + ' میلیون', + " میلیارد", + ' تریلیون', + " تریلیارد", +] + +farsiFrac = ["", "دهم", "صدم"] +farsiFracBig = ["", "هزارم", "میلیونیم", "میلیاردیم"] + +farsiSeperator = ' و ' + +class Num2Word_FA(object): + errmsg_too_big = "Too large" + max_num = 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(math.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 (res == ''): + res = yx + else: + res = yx + farsiSeperator + return res + + def fractional(self, number, l): + if (number == 5): + return "نیم" + x = self.cardinalPos(number) + ld3, lm3 = divmod(l, 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) + + def to_ordinal_num(self, value): + return str(value)+"م" + + def to_cardinal(self, number): + if number < 0: + return "منفی " + self.to_cardinal(-number) + if (number == 0): + return "صفر" + x, y, l = self.float2tuple(number) + if y == 0: + return self.cardinalPos(x) + if x == 0: + return self.fractional(y, l) + return self.cardinalPos(x) + farsiSeperator + self.fractional(y, l) \ No newline at end of file diff --git a/tests/test_fa.py b/tests/test_fa.py new file mode 100644 index 00000000..dbe9574c --- /dev/null +++ b/tests/test_fa.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. +# 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'), "دویست و چهل و دو") + + + + 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") From 1f6ac0a7e33fd29a9f659d58f12604092fb0ee8c Mon Sep 17 00:00:00 2001 From: Israel Teixeira Date: Tue, 22 Dec 2020 07:43:10 -0300 Subject: [PATCH 082/340] Remove dupplicated line in lang_PT_BR Remove an unnecessary condition, since the very same action follows it. --- num2words/lang_PT_BR.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 4c73cac3..80eb5e71 100644 --- a/num2words/lang_PT_BR.py +++ b/num2words/lang_PT_BR.py @@ -53,8 +53,6 @@ def merge(self, curr, next): ctext = "cento" if nnum < cnum: - if cnum < 100: - return ("%s e %s" % (ctext, ntext), cnum + nnum) return ("%s e %s" % (ctext, ntext), cnum + nnum) elif (not nnum % 1000000) and cnum > 1: From d90f99d4a4797613e9d2d483a76182894330cbe2 Mon Sep 17 00:00:00 2001 From: Maroua Romdhane Date: Thu, 21 Jan 2021 14:24:38 -0500 Subject: [PATCH 083/340] [UPD] Readme file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index db64202b..c84b491f 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -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 From b191c1fe1eca031a1fa144b66ea859b9ca5793d2 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Sun, 24 Jan 2021 10:10:24 +0330 Subject: [PATCH 084/340] fix test coverage --- num2words/lang_FA.py | 4 +++- tests/test_fa.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index 9e232a79..ca7004ca 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -123,10 +123,12 @@ def cardinalPos(self, number): if (y == 0): continue yx = self.cardinal3(y) + b + if b == ' هزار' and y == 1: + yx = 'هزار' if (res == ''): res = yx else: - res = yx + farsiSeperator + res = yx + farsiSeperator + res return res def fractional(self, number, l): diff --git a/tests/test_fa.py b/tests/test_fa.py index dbe9574c..4082e7f1 100644 --- a/tests/test_fa.py +++ b/tests/test_fa.py @@ -58,8 +58,24 @@ def test_ordinal(self): 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م') From ca2651ad0f71632a0681805f83fedb63cb35769e Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Sun, 24 Jan 2021 10:30:06 +0330 Subject: [PATCH 085/340] remove unneccery if --- num2words/lang_FA.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index ca7004ca..9c5ff749 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -90,14 +90,7 @@ def float2tuple(self, value): 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(math.floor(post)) + post = int(math.floor(post)) return pre, post, self.precision From a51b3e4d2be219818467cd2a06eb0d312d30da58 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Mon, 25 Jan 2021 00:14:05 +0330 Subject: [PATCH 086/340] try fix test failure --- num2words/lang_FA.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index 9c5ff749..f49b5f35 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -90,8 +90,14 @@ def float2tuple(self, value): self.precision = abs(Decimal(str(value)).as_tuple().exponent) post = abs(value - pre) * 10**self.precision - post = int(math.floor(post)) - + 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 From 5bb2be74a2d24c3adfc3cbba653b7a95ed6332ee Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Mon, 25 Jan 2021 01:16:45 +0330 Subject: [PATCH 087/340] fix format problem --- num2words/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 0b85ec7f..67b86316 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,12 +18,12 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, - lang_VI) + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, + lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, + lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, + lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, + lang_RO, lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, + lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), From 6cbd81cfbb291eccbed6bd79206caead8938ce06 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Mon, 25 Jan 2021 10:34:01 +0330 Subject: [PATCH 088/340] fix flake8 problems --- num2words/lang_FA.py | 17 ++++++++--------- tests/test_fa.py | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index f49b5f35..96e9e526 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -17,7 +17,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA -import re from decimal import Decimal from math import floor @@ -76,6 +75,7 @@ farsiSeperator = ' و ' + class Num2Word_FA(object): errmsg_too_big = "Too large" max_num = 10 ** 36 @@ -100,7 +100,6 @@ def float2tuple(self, value): post = int(floor(post)) return pre, post, self.precision - def cardinal3(self, number): if (number < 19): return farsiOnes[number] @@ -108,12 +107,12 @@ def cardinal3(self, number): x, y = divmod(number, 10) if y == 0: return farsiTens[x] - return farsiTens[x] + farsiSeperator + farsiOnes[y] + 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 = '' @@ -130,11 +129,11 @@ def cardinalPos(self, number): res = yx + farsiSeperator + res return res - def fractional(self, number, l): + def fractional(self, number, level): if (number == 5): return "نیم" x = self.cardinalPos(number) - ld3, lm3 = divmod(l, 3) + ld3, lm3 = divmod(level, 3) ltext = (farsiFrac[lm3] + " " + farsiFracBig[ld3]).strip() return x + " " + ltext @@ -158,9 +157,9 @@ def to_cardinal(self, number): return "منفی " + self.to_cardinal(-number) if (number == 0): return "صفر" - x, y, l = self.float2tuple(number) + x, y, level = self.float2tuple(number) if y == 0: return self.cardinalPos(x) if x == 0: - return self.fractional(y, l) - return self.cardinalPos(x) + farsiSeperator + self.fractional(y, l) \ No newline at end of file + return self.fractional(y, level) + return self.cardinalPos(x) + farsiSeperator + self.fractional(y, level) diff --git a/tests/test_fa.py b/tests/test_fa.py index 4082e7f1..9a9c4ead 100644 --- a/tests/test_fa.py +++ b/tests/test_fa.py @@ -62,16 +62,21 @@ def test_cardinal(self): 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'), "هزار و چهارصد") - + 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(1000, lang='fa', to='currency'), 'هزار تومان') self.assertEqual( num2words(1500000, lang='fa', to='currency'), 'یک میلیون و پانصد هزار تومان' @@ -86,9 +91,12 @@ def test_ordinal_num(self): 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(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): From 3b52c5f92411db6ddd4ef91e8371c2eff25767db Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 25 Jan 2021 14:30:43 +0100 Subject: [PATCH 089/340] updated test case to increase coverage. raised NotImplementedError for options not implemented. --- num2words/lang_SV.py | 20 ++++++++++---------- tests/test_sv.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 12ba9ae9..34a8827c 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -96,22 +96,22 @@ def to_ordinal(self, value): lastword_ending = self.ords[lastword[-3:]] ending_length = 3 except KeyError: - lastword += "de" - lastword_first_part = self.title(lastword)[:-ending_length] + # lastword += "de" + 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): - self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + raise NotImplementedError("'ordinal_num' is not implemented for swedish language") def to_year(self, val, longval=True): - if not (val // 100) % 10: - return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="hundra", jointxt="och", - longval=longval) + raise NotImplementedError("'year' is not implemented for swedish language") + def to_currency(self, val, longval=True): - return self.to_splitnum(val, hightxt="krone/r", lowtxt="öre/n", - jointxt="och", longval=longval, cents=True) + raise NotImplementedError("'currency' is not implemented for swedish language") diff --git a/tests/test_sv.py b/tests/test_sv.py index e4ce4662..fffbd0e0 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -24,6 +24,7 @@ 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") @@ -44,3 +45,17 @@ def test_cardinal(self): self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två 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)) \ No newline at end of file From 5611325b9db7e50e3e4e203e9741f79e6d6f05a3 Mon Sep 17 00:00:00 2001 From: Israel Teixeira Date: Mon, 25 Jan 2021 22:28:49 -0300 Subject: [PATCH 090/340] This error is already raised in line 223 --- num2words/lang_PT.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/num2words/lang_PT.py b/num2words/lang_PT.py index 6f459726..ddfa7713 100644 --- a/num2words/lang_PT.py +++ b/num2words/lang_PT.py @@ -227,12 +227,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' e', 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', From 400917aa89af6f8e36c4693bc92cc52553e572d6 Mon Sep 17 00:00:00 2001 From: Fernanda Hernandez Date: Wed, 23 Dec 2020 11:50:06 -0600 Subject: [PATCH 091/340] Add translations to spanish of several currencies --- num2words/lang_ES.py | 191 ++- tests/test_es.py | 2826 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 3014 insertions(+), 3 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index a8cc47de..d6fa77aa 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -21,13 +21,190 @@ from .lang_EU import Num2Word_EU +GENERIC_DOLLARS = ('dolar', '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') + class Num2Word_ES(Num2Word_EU): CURRENCY_FORMS = { 'EUR': (('euro', 'euros'), ('céntimo', 'céntimos')), 'ESP': (('peseta', 'pesetas'), ('céntimo', 'céntimos')), - 'USD': (('dolar', 'dólares'), ('centavo', 'centavos')), + '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'), ('penny', 'pence')), + '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'), ('penny', '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'), ('penny', '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 dolares'), ('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?? @@ -176,4 +353,14 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', 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") + # except in this currencies: leona, corona, + # libra, rupia, lempira, peseta, is 'una' + # but only when it's first word, otherwise + # it's replaced in others words like 'veintiun' + 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 diff --git a/tests/test_es.py b/tests/test_es.py index d306981b..cf3a8c2b 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -124,7 +124,7 @@ ) TEST_CASES_TO_CURRENCY_ESP = ( - (1.00, 'un peseta con cero céntimos'), + (1.00, 'una peseta con cero céntimos'), (2.00, 'dos pesetas con cero céntimos'), (8.00, 'ocho pesetas con cero céntimos'), (12.00, 'doce pesetas con cero céntimos'), @@ -156,6 +156,1661 @@ (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, 'veintiun 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 pence'), + (2.00, 'dos libras con cero pence'), + (8.00, 'ocho libras con cero pence'), + (12.00, 'doce libras con cero pence'), + (21.00, 'veintiun libras con cero pence'), + (81.25, 'ochenta y un libras con veinticinco pence'), + (350.90, 'trescientos cincuenta libras con noventa pence'), + (100.00, 'cien libras con cero pence'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres pence'), +) + +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, 'veintiun 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, 'veintiun coronas con cero öre'), + (81.25, 'ochenta y un coronas con veinticinco öre'), + (350.90, 'trescientos 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, 'veintiun coronas con cero øre'), + (81.25, 'ochenta y un coronas con veinticinco øre'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun coronas con cero haléř'), + (81.25, 'ochenta y un coronas con veinticinco haléř'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'un 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, 'veintiun liras con cero kuruş'), + (81.25, 'ochenta y un liras con veinticinco kuruş'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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 dolar 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero céntimos'), + (81.25, 'ochenta y un libras con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun coronas con cero øre'), + (81.25, 'ochenta y un coronas con veinticinco øre'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero piastras'), + (81.25, 'ochenta y un libras con veinticinco piastras'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun coronas con cero aurar'), + (81.25, 'ochenta y un coronas con veinticinco aurar'), + (350.90, 'trescientos 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, 'un 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, 'veintiun liras con cero céntimos'), + (81.25, 'ochenta y un liras con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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, 'veintiun coronas con cero haliers'), + (81.25, 'ochenta y un coronas con veinticinco haliers'), + (350.90, 'trescientos 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, 'veintiun leonas con cero céntimos'), + (81.25, 'ochenta y un leonas con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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 dolares 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 dolares con cero céntimos'), + (8.00, 'ocho nuevos dolares con cero céntimos'), + (12.00, 'doce nuevos dolares con cero céntimos'), + (21.00, 'veintiun nuevos dolares con cero céntimos'), + (81.25, 'ochenta y un nuevos dolares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta nuevos dolares con noventa céntimos'), + (100.00, 'cien nuevos dolares 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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'), +) + class Num2WordsESTest(TestCase): @@ -204,3 +1859,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='QTQ'), + 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] + ) From e6fb2b128b57eb2f8ec228fd198d0d4bdfe7dafd Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Tue, 26 Jan 2021 08:40:17 +0100 Subject: [PATCH 092/340] updated failing flake8 test --- num2words/__init__.py | 5 ++--- num2words/lang_SV.py | 4 +--- tests/test_sv.py | 37 +++++++++++++++++++++++-------------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 6d40774c..a8c47370 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, - lang_VI) + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, + lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -68,7 +68,6 @@ 'hu': lang_HU.Num2Word_HU() } - CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 34a8827c..afdd31ee 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -86,17 +86,15 @@ def to_ordinal(self, value): self.verify_ordinal(value) outwords = self.to_cardinal(value).split(" ") lastword = outwords[-1] - # lastword = lastwords[-1].lower() ending_length = 0 try: lastword_ending = self.ords[lastword[-4:]] ending_length = 4 - except: + except KeyError: try: lastword_ending = self.ords[lastword[-3:]] ending_length = 3 except KeyError: - # lastword += "de" lastword_ending = "de" if lastword_ending == 'de': lastword_first_part = self.title(lastword)[:] diff --git a/tests/test_sv.py b/tests/test_sv.py index fffbd0e0..a780dae2 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -25,8 +25,10 @@ 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(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") @@ -34,28 +36,35 @@ def test_ordinal(self): 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(2, to="cardinal", lang="sv"), "två") + self.assertEqual(num2words(3, to="cardinal", lang="sv"), "tre") self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem") - self.assertEqual(num2words(8, to="cardinal", lang="sv"), "åtta") self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton") self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem") - self.assertEqual(num2words(1245, to="cardinal", lang="sv"), "etttusen tvåhundraförtiofem") - self.assertEqual(num2words(4235, to="cardinal", lang="sv"), "fyratusen tvåhundratrettiofem") - self.assertEqual(num2words(1004135, to="cardinal", lang="sv"), "en miljon fyratusen etthundratrettiofem") - self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") - self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") - self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två fem") + 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)) + 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)) + 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)) \ No newline at end of file + self.assertTrue("'ordinal_num' is not implemented for swedish language" + in str(context.exception)) From 219c2a5eb4efc77b8bfd7db918e64a4a21c11d02 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Wed, 27 Jan 2021 08:09:27 +0100 Subject: [PATCH 093/340] split some lines that were too long for flake8 --- num2words/lang_SV.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index afdd31ee..4e32841c 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -42,7 +42,7 @@ def setup(self): self.exclude_title = ["och", "komma", "minus"] self.mid_numwords = [(1000, "tusen"), (100, "hundra"), - (90, "nittio"), (80, "\åttio"), (70, "sjuttio"), + (90, "nittio"), (80, "åttio"), (70, "sjuttio"), (60, "sextio"), (50, "femtio"), (40, "förtio"), (30, "trettio")] self.low_numwords = ["tjugo", "nitton", "arton", "sjutton", @@ -105,11 +105,13 @@ def to_ordinal(self, value): return " ".join(outwords) def to_ordinal_num(self, value): - raise NotImplementedError("'ordinal_num' is not implemented for swedish language") + 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") - + 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") + raise NotImplementedError( + "'currency' is not implemented for swedish language") From 94db9521b06f69bd5ba0f9f88fa131d0aa1f2f78 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Thu, 28 Jan 2021 08:09:56 +0100 Subject: [PATCH 094/340] updated readme (added swedish) --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index c84b491f..ab4cf652 100644 --- a/README.rst +++ b/README.rst @@ -107,6 +107,7 @@ Besides the numerical argument, there are two main optional arguments. * ``pt_BR`` (Portuguese - Brazilian) * ``sl`` (Slovene) * ``sr`` (Serbian) +* ``sv`` (Swedish) * ``ro`` (Romanian) * ``ru`` (Russian) * ``te`` (Telugu) From 21d02eaec9ae3a8e903ac36ef2ee77462df786c3 Mon Sep 17 00:00:00 2001 From: Jonas Triki Date: Sat, 6 Feb 2021 14:42:28 +0100 Subject: [PATCH 095/340] Fixes #339 --- num2words/lang_DK.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 From 9082085d59e3e4b8c001db37e17b1bd7462e707f Mon Sep 17 00:00:00 2001 From: Erwin de Haan <1627021+EraYaN@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:56:24 +0100 Subject: [PATCH 096/340] Fix ordinal_num output for Dutch (NL) --- num2words/lang_NL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_NL.py b/num2words/lang_NL.py index ac4d4051..00d6c5bb 100644 --- a/num2words/lang_NL.py +++ b/num2words/lang_NL.py @@ -135,7 +135,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): """ From e4bfffaf55202c2797a88e423508051bc332fafe Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Wed, 31 Mar 2021 22:03:00 +0000 Subject: [PATCH 097/340] Added Icelandic cardinals and tests. Missing genders and plurals. --- .gitignore | 1 + num2words/__init__.py | 5 +- num2words/lang_IS.py | 110 ++++++++++++++++++++++++++++++++++++++++++ tests/test_is.py | 37 ++++++++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 num2words/lang_IS.py create mode 100644 tests/test_is.py diff --git a/.gitignore b/.gitignore index e5a9b78d..2a9b1bf8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dist *.egg-info /.tox .eggs/ +/venv/ diff --git a/num2words/__init__.py b/num2words/__init__.py index a8c47370..10f05bb7 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -23,7 +23,7 @@ lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, - lang_UK, lang_VI) + lang_UK, lang_VI, lang_IS) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -65,7 +65,8 @@ 'nl': lang_NL.Num2Word_NL(), 'uk': lang_UK.Num2Word_UK(), 'te': lang_TE.Num2Word_TE(), - 'hu': lang_HU.Num2Word_HU() + 'hu': lang_HU.Num2Word_HU(), + 'is': lang_IS.Num2Word_IS() } CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py new file mode 100644 index 00000000..3b572b6d --- /dev/null +++ b/num2words/lang_IS.py @@ -0,0 +1,110 @@ +# -*- 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_IS(lang_EU.Num2Word_EU): + GIGA_SUFFIX = "illjarðar" + MEGA_SUFFIX = "illjónir" + + def setup(self): + super(Num2Word_IS, self).setup() + + self.negword = "mínus " + self.pointword = "komma" + 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ögur", "þrjú", "tvö", + "eitt", "núll"] + self.ords = {"eitt": "fyrsti", + "tvö": "annar", + "þrjú": "þriðji", + "fjögur": "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, forms): + form = 0 if (n%10 == 1 and n%100 != 11) else 1 + return forms[form] + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif rnum > lnum: + return ("%s %s" % (ltext, rtext), lnum * rnum) + elif lnum > rnum and rnum in self.cards: + return ("%s og %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + outwords = self.to_cardinal(value).split(" ") + lastwords = outwords[-1].split("-") + lastword = lastwords[-1].lower() + try: + lastword = self.ords[lastword] + except KeyError: + if lastword[-1] == "y": + lastword = lastword[:-1] + "ie" + lastword += "th" + lastwords[-1] = self.title(lastword) + outwords[-1] = "-".join(lastwords) + return " ".join(outwords) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) + + def to_year(self, val, suffix=None, longval=True): + if val < 0: + val = abs(val) + suffix = 'BC' if not suffix else suffix + high, low = (val // 100, val % 100) + # If year is 00XX, X00X, or beyond 9999, go cardinal. + if (high == 0 + or (high % 10 == 0 and low < 10) + or high >= 100): + valtext = self.to_cardinal(val) + else: + hightext = self.to_cardinal(high) + if low == 0: + lowtext = "hundred" + elif low < 10: + lowtext = "oh-%s" % self.to_cardinal(low) + else: + lowtext = self.to_cardinal(low) + valtext = "%s %s" % (hightext, lowtext) + return (valtext if not suffix + else "%s %s" % (valtext, suffix)) diff --git a/tests/test_is.py b/tests/test_is.py new file mode 100644 index 00000000..68c307c9 --- /dev/null +++ b/tests/test_is.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 Num2WordsISTest(TestCase): + + def test_cardinal(self): + self.assertEqual(num2words(0, to="cardinal", lang="is"), "núll") + self.assertEqual(num2words(1, to="cardinal", lang="is"), "eitt") + self.assertEqual(num2words(2, to="cardinal", lang="is"), "tvö") + self.assertEqual(num2words(5, to="cardinal", lang="is"), "fimm") + self.assertEqual(num2words(8, to="cardinal", lang="is"), "átta") + self.assertEqual(num2words(18, to="cardinal", lang="is"), "átján") + 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"), "eitt þúsund tvö hundruð fjörutíu og fimm") + self.assertEqual(num2words(1010234045, to="cardinal", lang="is"), "einn milljarður tíu milljónir tvö hundruð þrjátíu og fjögur þúsund fjörutíu og fimm") \ No newline at end of file From 9ba0074fd041fd13325fa65610fb178dc4b60972 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Wed, 7 Apr 2021 23:43:14 +0000 Subject: [PATCH 098/340] Added genders and plurals for Icelandic cardinals. --- num2words/lang_IS.py | 108 +++++++++++++++++++++++-------------------- tests/test_is.py | 25 +++++++--- 2 files changed, 77 insertions(+), 56 deletions(-) diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py index 3b572b6d..9a90657b 100644 --- a/num2words/lang_IS.py +++ b/num2words/lang_IS.py @@ -19,17 +19,33 @@ 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ðar" - MEGA_SUFFIX = "illjónir" + GIGA_SUFFIX = "illjarður" + MEGA_SUFFIX = "illjón" def setup(self): - super(Num2Word_IS, self).setup() + 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" - self.exclude_title = ["og", "komma", "mínus"] + # 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"), @@ -38,12 +54,12 @@ def setup(self): 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ögur", "þrjú", "tvö", - "eitt", "núll"] - self.ords = {"eitt": "fyrsti", - "tvö": "annar", - "þrjú": "þriðji", - "fjögur": "fjórði", + "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", @@ -53,58 +69,52 @@ def setup(self): "ellefu": "ellefti", "tólf": "tólfti"} - def pluralize(self, n, forms): - form = 0 if (n%10 == 1 and n%100 != 11) else 1 - return forms[form] + 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 rnum > lnum: + 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): - self.verify_ordinal(value) - outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") - lastword = lastwords[-1].lower() - try: - lastword = self.ords[lastword] - except KeyError: - if lastword[-1] == "y": - lastword = lastword[:-1] + "ie" - lastword += "th" - lastwords[-1] = self.title(lastword) - outwords[-1] = "-".join(lastwords) - return " ".join(outwords) + raise NotImplementedError def to_ordinal_num(self, value): - self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + raise NotImplementedError def to_year(self, val, suffix=None, longval=True): - if val < 0: - val = abs(val) - suffix = 'BC' if not suffix else suffix - high, low = (val // 100, val % 100) - # If year is 00XX, X00X, or beyond 9999, go cardinal. - if (high == 0 - or (high % 10 == 0 and low < 10) - or high >= 100): - valtext = self.to_cardinal(val) - else: - hightext = self.to_cardinal(high) - if low == 0: - lowtext = "hundred" - elif low < 10: - lowtext = "oh-%s" % self.to_cardinal(low) - else: - lowtext = self.to_cardinal(low) - valtext = "%s %s" % (hightext, lowtext) - return (valtext if not suffix - else "%s %s" % (valtext, suffix)) + raise NotImplementedError diff --git a/tests/test_is.py b/tests/test_is.py index 68c307c9..13326988 100644 --- a/tests/test_is.py +++ b/tests/test_is.py @@ -26,12 +26,23 @@ 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"), "eitt") - self.assertEqual(num2words(2, to="cardinal", lang="is"), "tvö") - self.assertEqual(num2words(5, to="cardinal", lang="is"), "fimm") - self.assertEqual(num2words(8, to="cardinal", lang="is"), "átta") - self.assertEqual(num2words(18, to="cardinal", lang="is"), "átján") + 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"), "eitt þúsund tvö hundruð fjörutíu og fimm") - self.assertEqual(num2words(1010234045, to="cardinal", lang="is"), "einn milljarður tíu milljónir tvö hundruð þrjátíu og fjögur þúsund fjörutíu og fimm") \ No newline at end of file + self.assertEqual(num2words(-1245, to="cardinal", lang="is"), "mínus eitt þúsund tvö hundruð fjörutíu og fimm") + self.assertEqual(num2words(1002234045, to="cardinal", lang="is"), "einn milljarður 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") \ No newline at end of file From 880dd7465da76be592cda2001011070e2c1f8864 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 00:00:42 +0000 Subject: [PATCH 099/340] Fixing 'flake8' issues --- num2words/lang_IS.py | 1 + tests/test_is.py | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py index 9a90657b..3cd33cec 100644 --- a/num2words/lang_IS.py +++ b/num2words/lang_IS.py @@ -36,6 +36,7 @@ } class Num2Word_IS(lang_EU.Num2Word_EU): + GIGA_SUFFIX = "illjarður" MEGA_SUFFIX = "illjón" diff --git a/tests/test_is.py b/tests/test_is.py index 13326988..459f9826 100644 --- a/tests/test_is.py +++ b/tests/test_is.py @@ -25,18 +25,29 @@ 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(1002234045, to="cardinal", lang="is"), "einn milljarður tvær milljónir tvö hundruð þrjátíu og fjögur þúsund fjörutíu og fimm") + 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(1002234045, to="cardinal", lang="is"), + "einn milljarður 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") + 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): From e00e543a237d8ab094a4c1ca88569305f2a0b522 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 00:07:28 +0000 Subject: [PATCH 100/340] Fixing more 'flake8' issues --- num2words/lang_IS.py | 1 + tests/test_is.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py index 3cd33cec..b3cff766 100644 --- a/num2words/lang_IS.py +++ b/num2words/lang_IS.py @@ -35,6 +35,7 @@ "hundrað": ("hundrað", "hundruð"), } + class Num2Word_IS(lang_EU.Num2Word_EU): GIGA_SUFFIX = "illjarður" diff --git a/tests/test_is.py b/tests/test_is.py index 459f9826..0ca90a4f 100644 --- a/tests/test_is.py +++ b/tests/test_is.py @@ -56,4 +56,4 @@ def test_overflow(self): "0000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000", lang="is") \ No newline at end of file + "00000000000000000000000000000000", lang="is") From e509073a88dc91ab8513a71a5f848b2f33ceca60 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 00:11:55 +0000 Subject: [PATCH 101/340] Fixing 'isort' issues --- num2words/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 10f05bb7..e1f8bfb4 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -20,10 +20,10 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, - lang_UK, lang_VI, lang_IS) + 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_SL, lang_SR, lang_SV, lang_TE, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), From be7a6ff33cab7cb68372e4eadbe34d2ddc4fd057 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 00:59:19 +0000 Subject: [PATCH 102/340] Final touches. --- README.rst | 1 + num2words/lang_EU.py | 6 ++++-- num2words/lang_IS.py | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index ab4cf652..9064d120 100644 --- a/README.rst +++ b/README.rst @@ -94,6 +94,7 @@ Besides the numerical argument, there are two main optional arguments. * ``he`` (Hebrew) * ``hu`` (Hungarian) * ``id`` (Indonesian) +* ``is`` (Icelandic) * ``it`` (Italian) * ``ja`` (Japanese) * ``kn`` (Kannada) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 09d39c15..204400cf 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -43,7 +43,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), - 'HUF': (('forint', 'forint'), ('fillér', 'fillér')) + 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), + 'ISK': (('króna', 'krónur'), ('aur', 'aurar')) } CURRENCY_ADJECTIVES = { @@ -56,7 +57,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': 'Mexican', 'RON': 'Romanian', 'INR': 'Indian', - 'HUF': 'Hungarian' + 'HUF': 'Hungarian', + 'ISK': 'íslenskar' } GIGA_SUFFIX = "illiard" diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py index b3cff766..e29eb7a7 100644 --- a/num2words/lang_IS.py +++ b/num2words/lang_IS.py @@ -47,7 +47,9 @@ def setup(self): self.negword = "mínus " self.pointword = "komma" - # self.exclude_title = ["og", "komma", "mínus"] + + # 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"), @@ -120,3 +122,6 @@ def to_ordinal_num(self, value): def to_year(self, val, suffix=None, longval=True): raise NotImplementedError + + def to_currency(self, val, longval=True): + raise NotImplementedError From 947419d3d4012b1c8d7088cc8cfc5c3107348914 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 09:17:50 +0000 Subject: [PATCH 103/340] Added test coverage. --- tests/test_is.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/test_is.py b/tests/test_is.py index 0ca90a4f..a4d58f28 100644 --- a/tests/test_is.py +++ b/tests/test_is.py @@ -35,8 +35,11 @@ def test_cardinal(self): "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(1002234045, to="cardinal", lang="is"), - "einn milljarður tvær milljónir tvö hundruð " + 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): @@ -57,3 +60,20 @@ def test_overflow(self): "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") From 5a98abf46bf738451333056fe15ea34909a01622 Mon Sep 17 00:00:00 2001 From: Birgir Steinarsson Date: Thu, 8 Apr 2021 16:55:07 +0000 Subject: [PATCH 104/340] Added test coverage. --- tests/test_is.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_is.py b/tests/test_is.py index a4d58f28..2a836d51 100644 --- a/tests/test_is.py +++ b/tests/test_is.py @@ -62,18 +62,18 @@ def test_overflow(self): "00000000000000000000000000000000", lang="is") def test_not_implemented(self): - #Ordinals + # Ordinals with self.assertRaises(NotImplementedError): num2words(1, to="ordinal", lang="is") - #Ordinal num + # Ordinal num with self.assertRaises(NotImplementedError): num2words(1, to="ordinal_num", lang="is") - #Year + # Year with self.assertRaises(NotImplementedError): num2words(1, to="year", lang="is") - #Currency + # Currency with self.assertRaises(NotImplementedError): num2words(1, to="currency", lang="is") From 3f5f6163cd1efcba3a7b78a8386c70f3da3a4521 Mon Sep 17 00:00:00 2001 From: Paulina Komorek <46355739+PaulinaKomorek@users.noreply.github.com> Date: Fri, 23 Apr 2021 21:27:47 +0200 Subject: [PATCH 105/340] [ADD] polish ordinal numbers (#367) --- num2words/lang_PL.py | 94 +++++++++++++++++++++++++++++++++++++++++++- tests/test_pl.py | 29 ++++++++++++-- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 2fa52f79..0f2bd751 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -36,6 +36,28 @@ 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',), @@ -49,6 +71,7 @@ 9: ('dziewiętnaście',), } + TWENTIES = { 2: ('dwadzieścia',), 3: ('trzydzieści',), @@ -60,6 +83,17 @@ 9: ('dziewięćdzisią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ęćdzisiąty', "dziewięćdziesięcio"), +} + HUNDREDS = { 1: ('sto',), 2: ('dwieście',), @@ -72,10 +106,28 @@ 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 @@ -130,8 +182,48 @@ def pluralize(self, n, forms): 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): - raise NotImplementedError() + 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: diff --git a/tests/test_pl.py b/tests/test_pl.py index ec76ed8c..a268c269 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -83,9 +83,32 @@ def test_cardinal(self): ) def test_to_ordinal(self): - # @TODO: implement to_ordinal - with self.assertRaises(NotImplementedError): - num2words(1, lang='pl', to='ordinal') + self.assertEqual(num2words(100, lang='pl', to='ordinal'), "setny") + self.assertEqual( + num2words(101, lang='pl', to='ordinal'), "sto pierwszy") + 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_currency(self): self.assertEqual( From 8061cf3b20c69d7272ab2d20193b0eae80f24b2b Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Fri, 7 May 2021 17:05:01 +0200 Subject: [PATCH 106/340] [tr] return Turkish 0 ordinal and cardinal (#347) * [tr] return Turkish 0 ordinal and cardinal * add str_to_number to Turkish * try rather use Num2Word_Base --- num2words/lang_TR.py | 8 +++++++- tests/test_tr.py | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 51f415b9..7fba8711 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -18,8 +18,10 @@ 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" @@ -152,6 +154,8 @@ def to_cardinal(self, value): wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][0], "" ) + if self.integers_to_read[0][0] == "0": + return self.ZERO return wrd if self.total_digits_outside_triplets == 0: @@ -507,6 +511,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: diff --git a/tests/test_tr.py b/tests/test_tr.py index a6fc968a..84252624 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -36,6 +36,7 @@ def test_tr(self): "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"}, @@ -108,6 +109,7 @@ def test_tr(self): "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"}, From 1e4470bc2401946d5ddeba71239eea9f0a779555 Mon Sep 17 00:00:00 2001 From: Antoine Planchot Date: Fri, 14 May 2021 22:31:46 +0200 Subject: [PATCH 107/340] Added support for Esperanto numbers. --- num2words/__init__.py | 13 +-- num2words/lang_EO.py | 130 +++++++++++++++++++++++++++++ tests/test_eo.py | 190 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 327 insertions(+), 6 deletions(-) create mode 100644 num2words/lang_EO.py create mode 100644 tests/test_eo.py diff --git a/num2words/__init__.py b/num2words/__init__.py index a8c47370..06004b66 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,12 +18,12 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, - lang_UK, lang_VI) + lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, + lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, + lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, + lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, + lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -36,6 +36,7 @@ '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_NI': lang_ES_NI.Num2Word_ES_NI(), diff --git a/num2words/lang_EO.py b/num2words/lang_EO.py new file mode 100644 index 00000000..473e74d1 --- /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." + ) + 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/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] + ) From 40ab739f6c384fb5b8c27c59eac1e5d75cf08c69 Mon Sep 17 00:00:00 2001 From: Rostyslav Ivanyk Date: Wed, 30 Jun 2021 20:23:46 +0300 Subject: [PATCH 108/340] Improve Ukrainian support and minor fixes in CZ, KZ, LT, LV, PL, RU, SR languages (#400) * Fix English char 'i' in Ukrainian words * Fix the feminine currency processing for UAH in lang_UK.py * Fix test_ua.py * Fix the feminine currency processing for UAH in lang_RU.py * Add tests for UAH in test_ru.py * Add world currencies to lang_UK.py; Add test cases to test_uk.py for world currencies * Fix incorrect handling of zeros after decimal point for CZ, KZ, LT, LV, PL, RU, SR and UK languages * Add ukrainian ordinal numbers * Fix too long lines of code * Add test for negative cardinal number --- num2words/base.py | 6 +- num2words/lang_CZ.py | 5 +- num2words/lang_KZ.py | 3 +- num2words/lang_LT.py | 5 +- num2words/lang_LV.py | 5 +- num2words/lang_PL.py | 5 +- num2words/lang_RU.py | 10 +- num2words/lang_SR.py | 5 +- num2words/lang_UK.py | 747 ++++++++- tests/test_cz.py | 8 + tests/test_kz.py | 8 + tests/test_lt.py | 8 + tests/test_lv.py | 8 + tests/test_pl.py | 8 + tests/test_ru.py | 65 +- tests/test_sr.py | 8 + tests/test_uk.py | 3438 ++++++++++++++++++++++++++++++++++++++++-- 17 files changed, 4189 insertions(+), 153 deletions(-) diff --git a/num2words/base.py b/num2words/base.py index ccf52482..0929cb93 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -257,6 +257,9 @@ 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) @@ -290,12 +293,13 @@ def to_currency(self, val, currency='EUR', cents=True, separator=',', cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1) minus_str = "%s " % self.negword 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), separator, cents_str, 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_KZ.py b/num2words/lang_KZ.py index 2486325d..67df20ed 100644 --- a/num2words/lang_KZ.py +++ b/num2words/lang_KZ.py @@ -77,10 +77,11 @@ 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, - self._int2word(int(right)) + (ZERO + ' ') * leading_zero_count + self._int2word(int(right)) ) else: return self._int2word(int(n)) 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_PL.py b/num2words/lang_PL.py index 0f2bd751..1fb1fdcd 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -165,10 +165,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_RU.py b/num2words/lang_RU.py index e822d381..8e6c875b 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -144,10 +144,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)) @@ -201,8 +204,11 @@ def to_ordinal(self, number): outwords[-1] = self.title(lastword) return " ".join(outwords).strip() + def _money_verbose(self, number, currency): + return self._int2word(number, currency == 'UAH') + def _cents_verbose(self, number, currency): - return self._int2word(number, currency == 'RUB') + return self._int2word(number, currency in ('UAH', 'RUB')) def _int2word(self, n, feminine=False): if n < 0: diff --git a/num2words/lang_SR.py b/num2words/lang_SR.py index 74ff0f04..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) diff --git a/num2words/lang_UK.py b/num2words/lang_UK.py index 45f87124..a6c0a3bb 100644 --- a/num2words/lang_UK.py +++ b/num2words/lang_UK.py @@ -24,13 +24,13 @@ ONES_FEMININE = { 1: ('одна',), - 2: ('двi',), + 2: ('дві',), 3: ('три',), 4: ('чотири',), 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), + 6: ('шість',), + 7: ('сім',), + 8: ('вісім',), 9: ('дев\'ять',), } @@ -40,12 +40,34 @@ 3: ('три',), 4: ('чотири',), 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), + 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: ('одинадцять',), @@ -53,9 +75,9 @@ 3: ('тринадцять',), 4: ('чотирнадцять',), 5: ('п\'ятнадцять',), - 6: ('шiстнадцять',), - 7: ('сiмнадцять',), - 8: ('вiсiмнадцять',), + 6: ('шістнадцять',), + 7: ('сімнадцять',), + 8: ('вісімнадцять',), 9: ('дев\'ятнадцять',), } @@ -64,61 +86,642 @@ 3: ('тридцять',), 4: ('сорок',), 5: ('п\'ятдесят',), - 6: ('шiстдесят',), - 7: ('сiмдесят',), - 8: ('вiсiмдесят',), + 6: ('шістдесят',), + 7: ('сімдесят',), + 8: ('вісімдесят',), 9: ('дев\'яносто',), } +TWENTIES_ORDINALS = { + 2: ("двадцятий", "двадцяти"), + 3: ("тридцятий", "тридцяти"), + 4: ("сороковий", "сорока"), + 5: ("п'ятдесятий", "п'ятдесяти"), + 6: ("шістдесятий", "шістдесяти"), + 7: ("сімдесятий", "сімдесяти"), + 8: ("вісімдесятий", "вісімдесяти"), + 9: ("дев'яностий", "дев'яности"), +} + HUNDREDS = { 1: ('сто',), - 2: ('двiстi',), + 2: ('двісті',), 3: ('триста',), 4: ('чотириста',), 5: ('п\'ятсот',), - 6: ('шiстсот',), - 7: ('сiмсот',), - 8: ('вiсiмсот',), + 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 + 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 +} + +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): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') - return '%s %s %s' % ( + 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)) @@ -136,7 +739,7 @@ def pluralize(self, n, forms): return forms[form] - def _int2word(self, n, feminine=True): + def _int2word(self, n, feminine=False): if n < 0: return ' '.join([self.negword, self._int2word(abs(n))]) @@ -172,8 +775,78 @@ def _int2word(self, n, feminine=True): 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/tests/test_cz.py b/tests/test_cz.py index 660919b0..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" diff --git a/tests/test_kz.py b/tests/test_kz.py index 68f71f2f..83435640 100644 --- a/tests/test_kz.py +++ b/tests/test_kz.py @@ -44,6 +44,14 @@ 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): 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 754ca621..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") diff --git a/tests/test_pl.py b/tests/test_pl.py index a268c269..147a747c 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -32,6 +32,14 @@ def test_cardinal(self): 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 " diff --git a/tests/test_ru.py b/tests/test_ru.py index f2415aea..dc479758 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -75,6 +75,14 @@ def test_cardinal(self): def test_floating_point(self): self.assertEqual(num2words(5.2, lang='ru'), "пять запятая два") + self.assertEqual( + num2words(10.02, lang='ru'), + "десять запятая ноль два" + ) + self.assertEqual( + num2words(15.007, lang='ru'), + "пятнадцать запятая ноль ноль семь" + ) self.assertEqual( num2words(561.42, lang='ru'), "пятьсот шестьдесят один запятая сорок два" @@ -160,6 +168,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,36 +180,85 @@ 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', 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', 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', separator=' и'), 'сто один рубль и двадцать две копейки' ) self.assertEqual( - num2words(10121, lang='ru', to='currency', currency='EUR', + num2words(10122, lang='ru', to='currency', currency='UAH', separator=' и'), - 'сто один евро и двадцать один цент' + 'сто одна гривна и двадцать две копейки' ) self.assertEqual( num2words(-1251985, lang='ru', to='currency', currency='EUR', cents=False), 'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов' ) + self.assertEqual( + 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'), 'одна тысяча двести тридцать долларов, пятьдесят шесть центов' diff --git a/tests/test_sr.py b/tests/test_sr.py index c97a0930..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') diff --git a/tests/test_uk.py b/tests/test_uk.py index 69342120..84fb770a 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -21,115 +21,3343 @@ 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_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): - 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: + self.assertEqual(num2words(test[0], lang='uk'), 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', - # separator=u' та'), - # "сто один євро та одинадцять центiв" - # ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10122, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять двi копiйки" - ) - # self.assertEqual( - # num2words(10121, lang='uk', to='currency', currency='EUR', - # separator=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', separator=' и', - 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] + ) From 5374a0ee44acb9395097164803437ff35d87c4ce Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 17:00:13 +0500 Subject: [PATCH 109/340] Added Tajik language support --- README.rst | 1 + num2words/__init__.py | 5 +- num2words/lang_TG.py | 149 ++++++++++++++++++++++++++++++++++++++++++ tests/test_tg.py | 104 +++++++++++++++++++++++++++++ 4 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 num2words/lang_TG.py create mode 100644 tests/test_tg.py diff --git a/README.rst b/README.rst index ab4cf652..e4c9fcfa 100644 --- a/README.rst +++ b/README.rst @@ -111,6 +111,7 @@ Besides the numerical argument, there are two main optional arguments. * ``ro`` (Romanian) * ``ru`` (Russian) * ``te`` (Telugu) +* ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) * ``vi`` (Vietnamese) diff --git a/num2words/__init__.py b/num2words/__init__.py index a8c47370..2ec96e67 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, - lang_UK, lang_VI) + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -60,6 +60,7 @@ '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(), diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py new file mode 100644 index 00000000..cc0bf497 --- /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 + + elif self.MEGA_SUFFIX: + 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/tests/test_tg.py b/tests/test_tg.py new file mode 100644 index 00000000..2caa9cf1 --- /dev/null +++ b/tests/test_tg.py @@ -0,0 +1,104 @@ +# -*- 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): + self.assertEqual(num2words(100, 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(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"), + "як ҳазору дусаду си доллар, панҷову шаш сент", + ) \ No newline at end of file From 1d98e0261e53f27a2537b36d8ae82ebf63d41c32 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 18:51:22 +0500 Subject: [PATCH 110/340] Added test for OverflowError and ordinal_num --- tests/test_tg.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_tg.py b/tests/test_tg.py index 2caa9cf1..a846d701 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -24,7 +24,10 @@ 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"), "яксаду понздаҳ") @@ -101,4 +104,9 @@ def test_to_currency(self): 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ум", ) \ No newline at end of file From cdb2acb052cae15fb1e37dd3b70dfd8f79adc584 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 22:29:28 +0500 Subject: [PATCH 111/340] Added MEGA_SUFFIX and GIGA_SUFFIX tests --- num2words/lang_TG.py | 3 ++- tests/test_tg.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py index cc0bf497..8a028d58 100644 --- a/num2words/lang_TG.py +++ b/num2words/lang_TG.py @@ -43,7 +43,7 @@ def set_high_numwords(self, high): if n == 9: self.cards[10 ** n] = word + self.GIGA_SUFFIX - elif self.MEGA_SUFFIX: + else: self.cards[10 ** n] = word + self.MEGA_SUFFIX def setup(self): @@ -147,3 +147,4 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) + diff --git a/tests/test_tg.py b/tests/test_tg.py index a846d701..482913be 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -45,6 +45,9 @@ def test_cardinal(self): "як миллиарду дусаду сию чор миллиону панҷсаду шасту ҳафт ҳазору " "ҳаштсаду навад", ) + 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"), "минус понздаҳ") From 9b62e333d769acfb634b251187648309f3597269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Eski?= Date: Tue, 12 Oct 2021 10:09:49 +0300 Subject: [PATCH 112/340] [ADD] to ordinal number for Turkish --- num2words/lang_TR.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 7fba8711..59393c29 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -806,6 +806,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: From 84e6322006191ad1acc142f5557a1e7c7caacd67 Mon Sep 17 00:00:00 2001 From: Cris140 <60457418+Cris140@users.noreply.github.com> Date: Thu, 28 Oct 2021 14:53:27 -0400 Subject: [PATCH 113/340] Update lang_PT_BR.py --- num2words/lang_PT_BR.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 80eb5e71..2c50f03f 100644 --- a/num2words/lang_PT_BR.py +++ b/num2words/lang_PT_BR.py @@ -53,6 +53,8 @@ def merge(self, curr, next): ctext = "cento" if nnum < cnum: + if cnum < 100: + return ("%s e %s" % (ctext, ntext), cnum + nnum) return ("%s e %s" % (ctext, ntext), cnum + nnum) elif (not nnum % 1000000) and cnum > 1: @@ -75,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 ) From fe0d1850592f208dd1b3c369bffcccd98f31b53e Mon Sep 17 00:00:00 2001 From: Cris140 <60457418+Cris140@users.noreply.github.com> Date: Fri, 29 Oct 2021 22:42:10 -0400 Subject: [PATCH 114/340] Update lang_PT_BR.py To fix a problem with the thousands when the hundreds are exacts. --- num2words/lang_PT_BR.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 80eb5e71..2c50f03f 100644 --- a/num2words/lang_PT_BR.py +++ b/num2words/lang_PT_BR.py @@ -53,6 +53,8 @@ def merge(self, curr, next): ctext = "cento" if nnum < cnum: + if cnum < 100: + return ("%s e %s" % (ctext, ntext), cnum + nnum) return ("%s e %s" % (ctext, ntext), cnum + nnum) elif (not nnum % 1000000) and cnum > 1: @@ -75,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 ) From 86b9a00a671b0a2dbce8a8ec8d1c8988af393b69 Mon Sep 17 00:00:00 2001 From: "potapov.s" Date: Tue, 2 Nov 2021 12:59:24 +0300 Subject: [PATCH 115/340] - add uzs for ru and en --- num2words/lang_EU.py | 6 ++++-- num2words/lang_RU.py | 3 +++ tests/test_en.py | 6 ++++++ tests/test_ru.py | 5 +++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 09d39c15..529547a9 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -43,7 +43,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), - 'HUF': (('forint', 'forint'), ('fillér', 'fillér')) + 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), + 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')) } CURRENCY_ADJECTIVES = { @@ -56,7 +57,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': 'Mexican', 'RON': 'Romanian', 'INR': 'Indian', - 'HUF': 'Hungarian' + 'HUF': 'Hungarian', + 'UZS': 'Uzbekistan' } GIGA_SUFFIX = "illiard" diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 8e6c875b..166169c2 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -113,6 +113,9 @@ class Num2Word_RU(Num2Word_Base): 'KZT': ( ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') ), + 'UZS': ( + ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') + ), } def setup(self): diff --git a/tests/test_en.py b/tests/test_en.py index 6234ac98..e763841c 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -131,6 +131,12 @@ def test_to_currency(self): "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_ru.py b/tests/test_ru.py index dc479758..85d6dc3e 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -272,3 +272,8 @@ def test_to_currency(self): 'одна тысяча двести тридцать четыре доллара, пятьдесят шесть ' 'центов' ) + self.assertEqual( + num2words(10122, lang='ru', to='currency', currency='UZS', + separator=' и'), + 'сто один сум и двадцать два тийина' + ) From 74ba6ee3b38370853f4e24d5a5da8a8a898531c2 Mon Sep 17 00:00:00 2001 From: Daniel-EST Date: Fri, 28 Jan 2022 15:30:48 -0300 Subject: [PATCH 116/340] Fixes savoirfairelinux/num2words#435 --- num2words/lang_PT_BR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 80eb5e71..82e7eb4b 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: From 31a250eb9035ca301a183f3e19be82516aa68890 Mon Sep 17 00:00:00 2001 From: Daniel-EST Date: Fri, 28 Jan 2022 15:31:41 -0300 Subject: [PATCH 117/340] Tests fix for issue #435 --- tests/test_pt_BR.py | 6 ++++++ 1 file changed, 6 insertions(+) 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' ) From 9a47f62d1c4d661130afe20bdeeaccc3614fc83f Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Sat, 5 Feb 2022 13:16:55 +0100 Subject: [PATCH 118/340] BYN to EU and RU --- num2words/lang_EU.py | 2 ++ num2words/lang_RU.py | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 09d39c15..a23cf81f 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')), @@ -48,6 +49,7 @@ class Num2Word_EU(Num2Word_Base): CURRENCY_ADJECTIVES = { 'AUD': 'Australian', + 'BYN': 'Belarussian', 'CAD': 'Canadian', 'EEK': 'Estonian', 'USD': 'US', diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 8e6c875b..549710ef 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -113,6 +113,10 @@ class Num2Word_RU(Num2Word_Base): 'KZT': ( ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') ), + 'BYN': ( + ('белорусский рубль', 'белорусского рубля', 'белорусских рублей'), ('копейка', 'копейки', 'копеек') + ), + } def setup(self): @@ -208,7 +212,7 @@ def _money_verbose(self, number, currency): return self._int2word(number, currency == 'UAH') def _cents_verbose(self, number, currency): - return self._int2word(number, currency in ('UAH', 'RUB')) + return self._int2word(number, currency in ('UAH', 'RUB', 'BYN')) def _int2word(self, n, feminine=False): if n < 0: From dd8b8bd313ad99c04ef580f867649eee86f2d1d9 Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Sat, 5 Feb 2022 13:43:37 +0100 Subject: [PATCH 119/340] BYN to EU and RU + version --- bin/num2words | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/num2words b/bin/num2words index 068abf25..d89c142a 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.10" +__version__ = "0.5.11" __license__ = "LGPL" From 994f2eadf1e277e129bc046e33c90278e531e3ff Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Mon, 7 Feb 2022 20:57:47 +0100 Subject: [PATCH 120/340] BYN to EU and RU spelling corrected --- num2words/lang_RU.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 549710ef..43781a4d 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -114,7 +114,7 @@ class Num2Word_RU(Num2Word_Base): ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') ), 'BYN': ( - ('белорусский рубль', 'белорусского рубля', 'белорусских рублей'), ('копейка', 'копейки', 'копеек') + ('белорусский рубль', 'белорусских рубля', 'белорусских рублей'), ('копейка', 'копейки', 'копеек') ), } From b70a28dab7d8228cd6ae7930db31ac1c2a65968c Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Date: Sat, 19 Mar 2022 19:12:19 -0400 Subject: [PATCH 121/340] feat: ci: replace travis by github workflows --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 20 ------------------ requirements-test.txt | 1 + tox.ini | 19 ++++++++++------- 4 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9bc095e5 --- /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.6, 3.7, 3.8, 3.9, '3.10'] + + 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/.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/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/tox.ini b/tox.ini index 11c8f61b..11cf12a3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,17 @@ [tox] -envlist = flake8,isort,py27,py34,py35,py36,py37 +envlist = py36,py37,py38,py39,py310,flake8,isort + +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: isort, flake8, py310 + [testenv] -passenv = TRAVIS TRAVIS_* +passenv = GITHUB_* deps = coverage delegator.py @@ -25,8 +34,4 @@ deps = isort delegator.py commands = - isort --check-only --recursive --diff num2words tests - -[testenv:py27] -setenv = - PYTHONIOENCODING = UTF-8 + isort --check-only --float-to-top --diff num2words tests From cb1f132c1aab6f61afaf06285f4a762e20ab1cab Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Fri, 15 Jul 2022 10:11:08 +0300 Subject: [PATCH 122/340] USD to PL --- CHANGES.rst | 9 +++++++++ bin/num2words | 2 +- num2words/lang_PL.py | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 298f9db9..861e6abc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,15 @@ Changelog ========= +Version 0.5.12 -- 2022/07/15 +---------------------------- + +* USD added to PL + +Version 0.5.11 -- 2022/02/05 +---------------------------- + +* BYN to EU and RU Version 0.5.10 -- 2019/05/12 ---------------------------- diff --git a/bin/num2words b/bin/num2words index d89c142a..ce5e1393 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.11" +__version__ = "0.5.12" __license__ = "LGPL" diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 1fb1fdcd..88c9c47f 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -155,6 +155,9 @@ class Num2Word_PL(Num2Word_Base): '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): From bba96cf1fa2074258bf6df9509b98500d975301e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:09:55 +0100 Subject: [PATCH 123/340] =?UTF-8?q?Orthography=20fixes:=20added=202=20miss?= =?UTF-8?q?ing=20accents=20(dieciseis->diecis=C3=A9is=20;=20dolar->d=C3=B3?= =?UTF-8?q?lar)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index d6fa77aa..18e6da52 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -21,7 +21,7 @@ from .lang_EU import Num2Word_EU -GENERIC_DOLLARS = ('dolar', 'dólares') +GENERIC_DOLLARS = ('dólar', 'dólares') GENERIC_CENTS = ('centavo', 'centavos') CURRENCIES_UNA = ('SLL', 'SEK', 'NOK', 'CZK', 'DKK', 'ISK', 'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP', @@ -230,7 +230,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", From 7d613beb9d9276914e9dd7bc4c422d90b85b5052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:57:46 +0100 Subject: [PATCH 124/340] =?UTF-8?q?Orthography=20fix:=20added=20accent=20v?= =?UTF-8?q?eintiun->veinti=C3=BAn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 1 + 1 file changed, 1 insertion(+) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 18e6da52..6291fd7d 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -363,4 +363,5 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[0] = list_result[0].replace("uno", "una") result = " ".join(list_result) result = result.replace("uno", "un") + result = result.replace("veintiun", "veintiún") # correct orthography for this specific case return result From 30f23ccd13baf7a09ed548e728332c9fc8d5c5d4 Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:03:51 +0100 Subject: [PATCH 125/340] =?UTF-8?q?Orthography=20fixes:=20added=20missing?= =?UTF-8?q?=20accent=20(nuevos=20dolares->nuevos=20d=C3=B3lares);=20fixed?= =?UTF-8?q?=20accents=20in=20test=5Fes.py=20(diecis=C3=A9is,=20d=C3=B3lar,?= =?UTF-8?q?=20d=C3=B3lares,=20veinti=C3=BAn)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 2 +- tests/test_es.py | 282 +++++++++++++++++++++---------------------- 2 files changed, 142 insertions(+), 142 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 6291fd7d..ba22d131 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -184,7 +184,7 @@ class Num2Word_ES(Num2Word_EU): '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 dolares'), ('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')), diff --git a/tests/test_es.py b/tests/test_es.py index cf3a8c2b..da7ff35a 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'), @@ -117,7 +117,7 @@ (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, 'veintiun 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'), @@ -128,18 +128,18 @@ (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, 'veintiun pesetas con cero céntimos'), + (21.00, 'veintiún pesetas con cero céntimos'), (81.25, 'ochenta y un pesetas con veinticinco céntimos'), (350.90, 'trescientos 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'), + (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, 'veintiun 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'), @@ -150,7 +150,7 @@ (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, 'veintiun 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'), @@ -161,7 +161,7 @@ (2.00, 'dos colones con cero centavos'), (8.00, 'ocho colones con cero centavos'), (12.00, 'doce colones con cero centavos'), - (21.00, 'veintiun 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'), @@ -174,7 +174,7 @@ (2.00, 'dos libras con cero pence'), (8.00, 'ocho libras con cero pence'), (12.00, 'doce libras con cero pence'), - (21.00, 'veintiun libras con cero pence'), + (21.00, 'veintiún libras con cero pence'), (81.25, 'ochenta y un libras con veinticinco pence'), (350.90, 'trescientos cincuenta libras con noventa pence'), (100.00, 'cien libras con cero pence'), @@ -187,7 +187,7 @@ (2.00, 'dos rublos con cero kopeykas'), (8.00, 'ocho rublos con cero kopeykas'), (12.00, 'doce rublos con cero kopeykas'), - (21.00, 'veintiun 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'), @@ -200,7 +200,7 @@ (2.00, 'dos coronas con cero öre'), (8.00, 'ocho coronas con cero öre'), (12.00, 'doce coronas con cero öre'), - (21.00, 'veintiun coronas con cero öre'), + (21.00, 'veintiún coronas con cero öre'), (81.25, 'ochenta y un coronas con veinticinco öre'), (350.90, 'trescientos cincuenta coronas con noventa öre'), (100.00, 'cien coronas con cero öre'), @@ -213,7 +213,7 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiun coronas con cero øre'), + (21.00, 'veintiún coronas con cero øre'), (81.25, 'ochenta y un coronas con veinticinco øre'), (350.90, 'trescientos cincuenta coronas con noventa øre'), (100.00, 'cien coronas con cero øre'), @@ -226,7 +226,7 @@ (2.00, 'dos zlotys con cero groszy'), (8.00, 'ocho zlotys con cero groszy'), (12.00, 'doce zlotys con cero groszy'), - (21.00, 'veintiun 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'), @@ -239,7 +239,7 @@ (2.00, 'dos pesos con cero centavos'), (8.00, 'ocho pesos con cero centavos'), (12.00, 'doce pesos con cero centavos'), - (21.00, 'veintiun 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'), @@ -252,7 +252,7 @@ (2.00, 'dos leus con cero bani'), (8.00, 'ocho leus con cero bani'), (12.00, 'doce leus con cero bani'), - (21.00, 'veintiun 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'), @@ -265,7 +265,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -278,7 +278,7 @@ (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, 'veintiun 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'), @@ -291,7 +291,7 @@ (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, 'veintiun 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'), @@ -304,7 +304,7 @@ (2.00, 'dos yuanes con cero jiaos'), (8.00, 'ocho yuanes con cero jiaos'), (12.00, 'doce yuanes con cero jiaos'), - (21.00, 'veintiun 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'), @@ -317,7 +317,7 @@ (2.00, 'dos coronas con cero haléř'), (8.00, 'ocho coronas con cero haléř'), (12.00, 'doce coronas con cero haléř'), - (21.00, 'veintiun coronas con cero haléř'), + (21.00, 'veintiún coronas con cero haléř'), (81.25, 'ochenta y un coronas con veinticinco haléř'), (350.90, 'trescientos cincuenta coronas con noventa haléř'), (100.00, 'cien coronas con cero haléř'), @@ -330,7 +330,7 @@ (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, 'veintiun 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'), @@ -343,7 +343,7 @@ (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, 'veintiun 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'), @@ -356,7 +356,7 @@ (2.00, 'dos reales con cero centavos'), (8.00, 'ocho reales con cero centavos'), (12.00, 'doce reales con cero centavos'), - (21.00, 'veintiun 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'), @@ -369,7 +369,7 @@ (2.00, 'dos yenes con cero sen'), (8.00, 'ocho yenes con cero sen'), (12.00, 'doce yenes con cero sen'), - (21.00, 'veintiun 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'), @@ -382,7 +382,7 @@ (2.00, 'dos wones con cero jeon'), (8.00, 'ocho wones con cero jeon'), (12.00, 'doce wones con cero jeon'), - (21.00, 'veintiun 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'), @@ -395,7 +395,7 @@ (2.00, 'dos wones con cero chon'), (8.00, 'ocho wones con cero chon'), (12.00, 'doce wones con cero chon'), - (21.00, 'veintiun 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'), @@ -408,7 +408,7 @@ (2.00, 'dos liras con cero kuruş'), (8.00, 'ocho liras con cero kuruş'), (12.00, 'doce liras con cero kuruş'), - (21.00, 'veintiun liras con cero kuruş'), + (21.00, 'veintiún liras con cero kuruş'), (81.25, 'ochenta y un liras con veinticinco kuruş'), (350.90, 'trescientos cincuenta liras con noventa kuruş'), (100.00, 'cien liras con cero kuruş'), @@ -421,7 +421,7 @@ (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, 'veintiun 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'), @@ -434,7 +434,7 @@ (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, 'veintiun 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'), @@ -447,7 +447,7 @@ (2.00, 'dos hryvnias con cero kopiykas'), (8.00, 'ocho hryvnias con cero kopiykas'), (12.00, 'doce hryvnias con cero kopiykas'), - (21.00, 'veintiun 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'), @@ -460,7 +460,7 @@ (2.00, 'dos bahts con cero satang'), (8.00, 'ocho bahts con cero satang'), (12.00, 'doce bahts con cero satang'), - (21.00, 'veintiun 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'), @@ -473,7 +473,7 @@ (2.00, 'dos dirhams con cero fils'), (8.00, 'ocho dirhams con cero fils'), (12.00, 'doce dirhams con cero fils'), - (21.00, 'veintiun 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'), @@ -486,7 +486,7 @@ (2.00, 'dos afghanis con cero puls'), (8.00, 'ocho afghanis con cero puls'), (12.00, 'doce afghanis con cero puls'), - (21.00, 'veintiun 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'), @@ -499,7 +499,7 @@ (2.00, 'dos leke con cero qindarka'), (8.00, 'ocho leke con cero qindarka'), (12.00, 'doce leke con cero qindarka'), - (21.00, 'veintiun 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'), @@ -512,7 +512,7 @@ (2.00, 'dos drams con cero lumas'), (8.00, 'ocho drams con cero lumas'), (12.00, 'doce drams con cero lumas'), - (21.00, 'veintiun 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'), @@ -525,7 +525,7 @@ (2.00, 'dos florines con cero centavos'), (8.00, 'ocho florines con cero centavos'), (12.00, 'doce florines con cero centavos'), - (21.00, 'veintiun 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'), @@ -538,7 +538,7 @@ (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, 'veintiun 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'), @@ -551,7 +551,7 @@ (2.00, 'dos florines con cero centavos'), (8.00, 'ocho florines con cero centavos'), (12.00, 'doce florines con cero centavos'), - (21.00, 'veintiun 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'), @@ -564,7 +564,7 @@ (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, 'veintiun 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'), @@ -577,7 +577,7 @@ (2.00, 'dos takas con cero paisas'), (8.00, 'ocho takas con cero paisas'), (12.00, 'doce takas con cero paisas'), - (21.00, 'veintiun 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'), @@ -590,7 +590,7 @@ (2.00, 'dos leva con cero stotinki'), (8.00, 'ocho leva con cero stotinki'), (12.00, 'doce leva con cero stotinki'), - (21.00, 'veintiun 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'), @@ -603,7 +603,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -616,7 +616,7 @@ (2.00, 'dos bolivianos con cero centavos'), (8.00, 'ocho bolivianos con cero centavos'), (12.00, 'doce bolivianos con cero centavos'), - (21.00, 'veintiun 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'), @@ -629,7 +629,7 @@ (2.00, 'dos ngultrum con cero chetrum'), (8.00, 'ocho ngultrum con cero chetrum'), (12.00, 'doce ngultrum con cero chetrum'), - (21.00, 'veintiun 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'), @@ -642,7 +642,7 @@ (2.00, 'dos pulas con cero thebes'), (8.00, 'ocho pulas con cero thebes'), (12.00, 'doce pulas con cero thebes'), - (21.00, 'veintiun 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'), @@ -655,7 +655,7 @@ (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, 'veintiun 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'), @@ -668,7 +668,7 @@ (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, 'veintiun 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'), @@ -677,11 +677,11 @@ ) TEST_CASES_TO_CURRENCY_BZD = ( - (1.00, 'un dolar con cero céntimos'), + (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, 'veintiun 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'), @@ -694,7 +694,7 @@ (2.00, 'dos escudos con cero centavos'), (8.00, 'ocho escudos con cero centavos'), (12.00, 'doce escudos con cero centavos'), - (21.00, 'veintiun 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'), @@ -707,7 +707,7 @@ (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, 'veintiun libras con cero céntimos'), + (21.00, 'veintiún libras con cero céntimos'), (81.25, 'ochenta y un libras con veinticinco céntimos'), (350.90, 'trescientos cincuenta libras con noventa céntimos'), (100.00, 'cien libras con cero céntimos'), @@ -720,7 +720,7 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiun coronas con cero øre'), + (21.00, 'veintiún coronas con cero øre'), (81.25, 'ochenta y un coronas con veinticinco øre'), (350.90, 'trescientos cincuenta coronas con noventa øre'), (100.00, 'cien coronas con cero øre'), @@ -733,7 +733,7 @@ (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, 'veintiun 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'), @@ -746,7 +746,7 @@ (2.00, 'dos sucres con cero centavos'), (8.00, 'ocho sucres con cero centavos'), (12.00, 'doce sucres con cero centavos'), - (21.00, 'veintiun 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'), @@ -759,7 +759,7 @@ (2.00, 'dos libras con cero piastras'), (8.00, 'ocho libras con cero piastras'), (12.00, 'doce libras con cero piastras'), - (21.00, 'veintiun libras con cero piastras'), + (21.00, 'veintiún libras con cero piastras'), (81.25, 'ochenta y un libras con veinticinco piastras'), (350.90, 'trescientos cincuenta libras con noventa piastras'), (100.00, 'cien libras con cero piastras'), @@ -772,7 +772,7 @@ (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, 'veintiun 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'), @@ -785,7 +785,7 @@ (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, 'veintiun 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'), @@ -798,7 +798,7 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiun libras con cero peniques'), + (21.00, 'veintiún libras con cero peniques'), (81.25, 'ochenta y un libras con veinticinco peniques'), (350.90, 'trescientos cincuenta libras con noventa peniques'), (100.00, 'cien libras con cero peniques'), @@ -811,7 +811,7 @@ (2.00, 'dos laris con cero tetris'), (8.00, 'ocho laris con cero tetris'), (12.00, 'doce laris con cero tetris'), - (21.00, 'veintiun 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'), @@ -824,7 +824,7 @@ (2.00, 'dos cedis con cero pesewas'), (8.00, 'ocho cedis con cero pesewas'), (12.00, 'doce cedis con cero pesewas'), - (21.00, 'veintiun 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'), @@ -837,7 +837,7 @@ (2.00, 'dos dalasis con cero bututs'), (8.00, 'ocho dalasis con cero bututs'), (12.00, 'doce dalasis con cero bututs'), - (21.00, 'veintiun 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'), @@ -850,7 +850,7 @@ (2.00, 'dos quetzales con cero centavos'), (8.00, 'ocho quetzales con cero centavos'), (12.00, 'doce quetzales con cero centavos'), - (21.00, 'veintiun 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'), @@ -863,7 +863,7 @@ (2.00, 'dos lempiras con cero centavos'), (8.00, 'ocho lempiras con cero centavos'), (12.00, 'doce lempiras con cero centavos'), - (21.00, 'veintiun 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'), @@ -876,7 +876,7 @@ (2.00, 'dos kunas con cero lipas'), (8.00, 'ocho kunas con cero lipas'), (12.00, 'doce kunas con cero lipas'), - (21.00, 'veintiun 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'), @@ -889,7 +889,7 @@ (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, 'veintiun 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'), @@ -902,7 +902,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -915,7 +915,7 @@ (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, 'veintiun 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'), @@ -928,7 +928,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -941,7 +941,7 @@ (2.00, 'dos riales con cero dinares'), (8.00, 'ocho riales con cero dinares'), (12.00, 'doce riales con cero dinares'), - (21.00, 'veintiun 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'), @@ -954,7 +954,7 @@ (2.00, 'dos coronas con cero aurar'), (8.00, 'ocho coronas con cero aurar'), (12.00, 'doce coronas con cero aurar'), - (21.00, 'veintiun coronas con cero aurar'), + (21.00, 'veintiún coronas con cero aurar'), (81.25, 'ochenta y un coronas con veinticinco aurar'), (350.90, 'trescientos cincuenta coronas con noventa aurar'), (100.00, 'cien coronas con cero aurar'), @@ -967,7 +967,7 @@ (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, 'veintiun liras con cero céntimos'), + (21.00, 'veintiún liras con cero céntimos'), (81.25, 'ochenta y un liras con veinticinco céntimos'), (350.90, 'trescientos cincuenta liras con noventa céntimos'), (100.00, 'cien liras con cero céntimos'), @@ -980,7 +980,7 @@ (2.00, 'dos dinares con cero piastras'), (8.00, 'ocho dinares con cero piastras'), (12.00, 'doce dinares con cero piastras'), - (21.00, 'veintiun 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'), @@ -993,7 +993,7 @@ (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, 'veintiun 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'), @@ -1006,7 +1006,7 @@ (2.00, 'dos som con cero tyiyn'), (8.00, 'ocho som con cero tyiyn'), (12.00, 'doce som con cero tyiyn'), - (21.00, 'veintiun 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'), @@ -1019,7 +1019,7 @@ (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, 'veintiun 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'), @@ -1032,7 +1032,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -1045,7 +1045,7 @@ (2.00, 'dos kips con cero att'), (8.00, 'ocho kips con cero att'), (12.00, 'doce kips con cero att'), - (21.00, 'veintiun 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'), @@ -1058,7 +1058,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1071,7 +1071,7 @@ (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, 'veintiun 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'), @@ -1084,7 +1084,7 @@ (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, 'veintiun 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'), @@ -1097,7 +1097,7 @@ (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, 'veintiun 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'), @@ -1110,7 +1110,7 @@ (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, 'veintiun 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'), @@ -1123,7 +1123,7 @@ (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, 'veintiun 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'), @@ -1136,7 +1136,7 @@ (2.00, 'dos lei con cero bani'), (8.00, 'ocho lei con cero bani'), (12.00, 'doce lei con cero bani'), - (21.00, 'veintiun 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'), @@ -1149,7 +1149,7 @@ (2.00, 'dos ariaris con cero iraimbilanja'), (8.00, 'ocho ariaris con cero iraimbilanja'), (12.00, 'doce ariaris con cero iraimbilanja'), - (21.00, 'veintiun 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'), @@ -1162,7 +1162,7 @@ (2.00, 'dos denares con cero denis'), (8.00, 'ocho denares con cero denis'), (12.00, 'doce denares con cero denis'), - (21.00, 'veintiun 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'), @@ -1175,7 +1175,7 @@ (2.00, 'dos kiats con cero pyas'), (8.00, 'ocho kiats con cero pyas'), (12.00, 'doce kiats con cero pyas'), - (21.00, 'veintiun 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'), @@ -1188,7 +1188,7 @@ (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, 'veintiun 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ö'), @@ -1201,7 +1201,7 @@ (2.00, 'dos patacas con cero avos'), (8.00, 'ocho patacas con cero avos'), (12.00, 'doce patacas con cero avos'), - (21.00, 'veintiun 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'), @@ -1214,7 +1214,7 @@ (2.00, 'dos ouguiyas con cero khoums'), (8.00, 'ocho ouguiyas con cero khoums'), (12.00, 'doce ouguiyas con cero khoums'), - (21.00, 'veintiun 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'), @@ -1227,7 +1227,7 @@ (2.00, 'dos ouguiyas con cero khoums'), (8.00, 'ocho ouguiyas con cero khoums'), (12.00, 'doce ouguiyas con cero khoums'), - (21.00, 'veintiun 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'), @@ -1240,7 +1240,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1253,7 +1253,7 @@ (2.00, 'dos rufiyaas con cero laari'), (8.00, 'ocho rufiyaas con cero laari'), (12.00, 'doce rufiyaas con cero laari'), - (21.00, 'veintiun 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'), @@ -1266,7 +1266,7 @@ (2.00, 'dos kuachas con cero tambalas'), (8.00, 'ocho kuachas con cero tambalas'), (12.00, 'doce kuachas con cero tambalas'), - (21.00, 'veintiun 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'), @@ -1279,7 +1279,7 @@ (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, 'veintiun 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'), @@ -1292,7 +1292,7 @@ (2.00, 'dos metical con cero centavos'), (8.00, 'ocho metical con cero centavos'), (12.00, 'doce metical con cero centavos'), - (21.00, 'veintiun 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'), @@ -1305,7 +1305,7 @@ (2.00, 'dos nairas con cero kobo'), (8.00, 'ocho nairas con cero kobo'), (12.00, 'doce nairas con cero kobo'), - (21.00, 'veintiun 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'), @@ -1318,7 +1318,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -1331,7 +1331,7 @@ (2.00, 'dos riales con cero baisa'), (8.00, 'ocho riales con cero baisa'), (12.00, 'doce riales con cero baisa'), - (21.00, 'veintiun 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'), @@ -1344,7 +1344,7 @@ (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, 'veintiun 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'), @@ -1357,7 +1357,7 @@ (2.00, 'dos kinas con cero toea'), (8.00, 'ocho kinas con cero toea'), (12.00, 'doce kinas con cero toea'), - (21.00, 'veintiun 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'), @@ -1370,7 +1370,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -1383,7 +1383,7 @@ (2.00, 'dos zlotys con cero groszy'), (8.00, 'ocho zlotys con cero groszy'), (12.00, 'doce zlotys con cero groszy'), - (21.00, 'veintiun 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'), @@ -1396,7 +1396,7 @@ (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, 'veintiun 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'), @@ -1409,7 +1409,7 @@ (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, 'veintiun 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'), @@ -1422,7 +1422,7 @@ (2.00, 'dos dinares con cero para'), (8.00, 'ocho dinares con cero para'), (12.00, 'doce dinares con cero para'), - (21.00, 'veintiun 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'), @@ -1435,7 +1435,7 @@ (2.00, 'dos rublos con cero kopeks'), (8.00, 'ocho rublos con cero kopeks'), (12.00, 'doce rublos con cero kopeks'), - (21.00, 'veintiun 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'), @@ -1448,7 +1448,7 @@ (2.00, 'dos riales con cero halalas'), (8.00, 'ocho riales con cero halalas'), (12.00, 'doce riales con cero halalas'), - (21.00, 'veintiun 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'), @@ -1461,7 +1461,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1474,7 +1474,7 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiun libras con cero peniques'), + (21.00, 'veintiún libras con cero peniques'), (81.25, 'ochenta y un libras con veinticinco peniques'), (350.90, 'trescientos cincuenta libras con noventa peniques'), (100.00, 'cien libras con cero peniques'), @@ -1487,7 +1487,7 @@ (2.00, 'dos coronas con cero haliers'), (8.00, 'ocho coronas con cero haliers'), (12.00, 'doce coronas con cero haliers'), - (21.00, 'veintiun coronas con cero haliers'), + (21.00, 'veintiún coronas con cero haliers'), (81.25, 'ochenta y un coronas con veinticinco haliers'), (350.90, 'trescientos cincuenta coronas con noventa haliers'), (100.00, 'cien coronas con cero haliers'), @@ -1500,7 +1500,7 @@ (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, 'veintiun leonas con cero céntimos'), + (21.00, 'veintiún leonas con cero céntimos'), (81.25, 'ochenta y un leonas con veinticinco céntimos'), (350.90, 'trescientos cincuenta leonas con noventa céntimos'), (100.00, 'cien leonas con cero céntimos'), @@ -1513,7 +1513,7 @@ (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, 'veintiun 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'), @@ -1526,7 +1526,7 @@ (2.00, 'dos colones con cero centavos'), (8.00, 'ocho colones con cero centavos'), (12.00, 'doce colones con cero centavos'), - (21.00, 'veintiun 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'), @@ -1539,7 +1539,7 @@ (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, 'veintiun 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'), @@ -1552,7 +1552,7 @@ (2.00, 'dos somonis con cero dirames'), (8.00, 'ocho somonis con cero dirames'), (12.00, 'doce somonis con cero dirames'), - (21.00, 'veintiun 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'), @@ -1565,7 +1565,7 @@ (2.00, 'dos manat con cero tenge'), (8.00, 'ocho manat con cero tenge'), (12.00, 'doce manat con cero tenge'), - (21.00, 'veintiun 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'), @@ -1578,7 +1578,7 @@ (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, 'veintiun 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'), @@ -1591,7 +1591,7 @@ (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, 'veintiun 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'), @@ -1600,17 +1600,17 @@ ) wordamount = "{} {}".format("cuatro mil ciento cincuenta", - "nuevos dolares con ochenta y tres céntimos") + "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 dolares con cero céntimos'), - (8.00, 'ocho nuevos dolares con cero céntimos'), - (12.00, 'doce nuevos dolares con cero céntimos'), - (21.00, 'veintiun nuevos dolares con cero céntimos'), - (81.25, 'ochenta y un nuevos dolares con veinticinco céntimos'), - (350.90, 'trescientos cincuenta nuevos dolares con noventa céntimos'), - (100.00, 'cien nuevos dolares 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), ) @@ -1619,7 +1619,7 @@ (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, 'veintiun 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'), @@ -1632,7 +1632,7 @@ (2.00, 'dos hryvnias con cero kopiykas'), (8.00, 'ocho hryvnias con cero kopiykas'), (12.00, 'doce hryvnias con cero kopiykas'), - (21.00, 'veintiun 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'), @@ -1645,7 +1645,7 @@ (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, 'veintiun 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'), @@ -1658,7 +1658,7 @@ (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, 'veintiun 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'), @@ -1671,7 +1671,7 @@ (2.00, 'dos sum con cero tiyin'), (8.00, 'ocho sum con cero tiyin'), (12.00, 'doce sum con cero tiyin'), - (21.00, 'veintiun 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'), @@ -1687,7 +1687,7 @@ (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, 'veintiun 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'), @@ -1699,7 +1699,7 @@ (2.00, 'dos dongs con cero xu'), (8.00, 'ocho dongs con cero xu'), (12.00, 'doce dongs con cero xu'), - (21.00, 'veintiun 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'), @@ -1712,7 +1712,7 @@ (2.00, 'dos vatu con cero nenhum'), (8.00, 'ocho vatu con cero nenhum'), (12.00, 'doce vatu con cero nenhum'), - (21.00, 'veintiun 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'), @@ -1725,7 +1725,7 @@ (2.00, 'dos tala con cero centavos'), (8.00, 'ocho tala con cero centavos'), (12.00, 'doce tala con cero centavos'), - (21.00, 'veintiun 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'), @@ -1738,7 +1738,7 @@ (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, 'veintiun 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'), @@ -1751,7 +1751,7 @@ (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, 'veintiun 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'), @@ -1764,7 +1764,7 @@ (2.00, 'dos riales con cero fils'), (8.00, 'ocho riales con cero fils'), (12.00, 'doce riales con cero fils'), - (21.00, 'veintiun 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'), @@ -1777,7 +1777,7 @@ (2.00, 'dos dinares con cero para'), (8.00, 'ocho dinares con cero para'), (12.00, 'doce dinares con cero para'), - (21.00, 'veintiun 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'), @@ -1790,7 +1790,7 @@ (2.00, 'dos kwachas con cero ngwee'), (8.00, 'ocho kwachas con cero ngwee'), (12.00, 'doce kwachas con cero ngwee'), - (21.00, 'veintiun 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'), @@ -1803,7 +1803,7 @@ (2.00, 'dos zaires con cero makuta'), (8.00, 'ocho zaires con cero makuta'), (12.00, 'doce zaires con cero makuta'), - (21.00, 'veintiun 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'), From b60a58bc8562ea17970dac58be30e8282c3cc0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 18:25:37 +0100 Subject: [PATCH 126/340] flake8 fix: fixed comment style Fixed: ./num2words/lang_ES.py:366:56: E261 at least two spaces before inline comment ./num2words/lang_ES.py:366:80: E501 line too long (100 > 79 characters) --- num2words/lang_ES.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index ba22d131..ed66cbe1 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -363,5 +363,6 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[0] = list_result[0].replace("uno", "una") result = " ".join(list_result) result = result.replace("uno", "un") - result = result.replace("veintiun", "veintiún") # correct orthography for this specific case + # correct orthography for the specific case of "veintiún": + result = result.replace("veintiun", "veintiún") return result From 560224631985fe2bca13de7ef42f3c1f2a9baa30 Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:52:37 +0100 Subject: [PATCH 127/340] Fixed pound cents: penny->penique, pence->peniques; fixed tests accordingly --- num2words/lang_ES.py | 6 +++--- tests/test_es.py | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index ed66cbe1..80a630fa 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -39,7 +39,7 @@ class Num2Word_ES(Num2Word_EU): 'CRC': (('colón', 'colones'), GENERIC_CENTS), 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), - 'GBP': (('libra', 'libras'), ('penny', 'pence')), + 'GBP': (('libra', 'libras'), ('penique', 'peniques')), 'RUB': (('rublo', 'rublos'), ('kopeyka', 'kopeykas')), 'SEK': (('corona', 'coronas'), ('öre', 'öre')), 'NOK': (('corona', 'coronas'), ('øre', 'øre')), @@ -101,7 +101,7 @@ class Num2Word_ES(Num2Word_EU): 'ERN': (('nakfa', 'nakfas'), ('céntimo', 'céntimos')), 'ETB': (('birr', 'birrs'), ('céntimo', 'céntimos')), 'FJD': (GENERIC_DOLLARS, GENERIC_CENTS), - 'FKP': (('libra', 'libras'), ('penny', 'peniques')), + 'FKP': (('libra', 'libras'), ('penique', 'peniques')), 'GEL': (('lari', 'laris'), ('tetri', 'tetris')), 'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')), 'GIP': (('libra', 'libras'), ('penique', 'peniques')), @@ -170,7 +170,7 @@ class Num2Word_ES(Num2Word_EU): 'SCR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), 'SDG': (('libra', 'libras'), ('piastra', 'piastras')), 'SGD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), - 'SHP': (('libra', 'libras'), ('penny', 'peniques')), + 'SHP': (('libra', 'libras'), ('penique', 'peniques')), 'SKK': (('corona', 'coronas'), ('halier', 'haliers')), 'SLL': (('leona', 'leonas'), ('céntimo', 'céntimos')), 'SRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), diff --git a/tests/test_es.py b/tests/test_es.py index da7ff35a..2ac5f124 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -170,16 +170,16 @@ ) TEST_CASES_TO_CURRENCY_GBP = ( - (1.00, 'una libra con cero pence'), - (2.00, 'dos libras con cero pence'), - (8.00, 'ocho libras con cero pence'), - (12.00, 'doce libras con cero pence'), - (21.00, 'veintiún libras con cero pence'), - (81.25, 'ochenta y un libras con veinticinco pence'), - (350.90, 'trescientos cincuenta libras con noventa pence'), - (100.00, 'cien libras con cero pence'), - (4150.83, - 'cuatro mil ciento cincuenta libras con ochenta y tres pence'), + (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, 'veintiún libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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 = ( From 4f82655c74249aa3b879c0624637f04cfe396a6b Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:56:55 +0100 Subject: [PATCH 128/340] Added test covering new fix penny->penique --- tests/test_es.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_es.py b/tests/test_es.py index 2ac5f124..9032354c 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -171,6 +171,7 @@ 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'), From 996f5ddbd4efc482eba0f2e6e6fda0d1e8be28f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Sun, 6 Mar 2022 00:36:40 +0100 Subject: [PATCH 129/340] =?UTF-8?q?Fixed=20accent=20in=20examples=20("cent?= =?UTF-8?q?imos"->"c=C3=A9ntimos")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed accent in Spanish examples ("centimos"->"céntimos"), thus making the example consistent with actual current behaviour. --- bin/num2words | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/num2words b/bin/num2words index 068abf25..02cfc69e 100755 --- a/bin/num2words +++ b/bin/num2words @@ -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 From bd699be04735a60d4dddfc8c3867b4f1ec7934a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al=20Garc=C3=A9s=20D=C3=ADaz-Mun=C3=ADo?= <11833677+gonsalet@users.noreply.github.com> Date: Mon, 21 Mar 2022 16:33:07 +0100 Subject: [PATCH 130/340] Fixed accent in Spanish command line examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed accent in Spanish command line examples ("centimos"->"céntimos"), thus making the example consistent with actual current behaviour. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ab4cf652..282aef23 100644 --- a/README.rst +++ b/README.rst @@ -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:: From 72f1f88c2c23277a8db0f807a70ae5cfec73e063 Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Wed, 23 Mar 2022 04:34:52 +0100 Subject: [PATCH 131/340] lang_ES: improved currency gender handling, improved error messages; test_es: updated accordingly --- num2words/lang_ES.py | 70 +++++++++++++++++----- tests/test_es.py | 137 ++++++++++++++++++++++--------------------- 2 files changed, 124 insertions(+), 83 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 80a630fa..5d086d8b 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -27,7 +27,8 @@ 'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP', 'LBP', 'SDG', 'SHP', 'SSP', 'SYP', 'INR', 'IDR', 'LKR', 'MUR', 'NPR', 'PKR', 'SCR', - 'ESP') + 'ESP', 'TRY', 'ITL') +CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP') class Num2Word_ES(Num2Word_EU): @@ -216,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"] @@ -352,17 +357,52 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', result = super(Num2Word_ES, self).to_currency( val, currency=currency, cents=cents, separator=separator, adjective=adjective) - # Handle exception, in spanish is "un euro" and not "uno euro" - # except in this currencies: leona, corona, - # libra, rupia, lempira, peseta, is 'una' - # but only when it's first word, otherwise - # it's replaced in others words like 'veintiun' + # 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(" con ") + + # "DOLLARS" PART (list_result[0]) + + # Feminine currencies ("una libra", "trescientas libras"...) 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") - # correct orthography for the specific case of "veintiún": - result = result.replace("veintiun", "veintiún") + + # "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 = " con ".join(list_result) + return result diff --git a/tests/test_es.py b/tests/test_es.py index 9032354c..e014b811 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -128,9 +128,9 @@ (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, 'veintiún pesetas con cero céntimos'), - (81.25, 'ochenta y un pesetas con veinticinco céntimos'), - (350.90, 'trescientos cincuenta pesetas con noventa 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'), ) @@ -175,9 +175,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -201,9 +201,9 @@ (2.00, 'dos coronas con cero öre'), (8.00, 'ocho coronas con cero öre'), (12.00, 'doce coronas con cero öre'), - (21.00, 'veintiún coronas con cero öre'), - (81.25, 'ochenta y un coronas con veinticinco öre'), - (350.90, 'trescientos cincuenta coronas con noventa ö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'), @@ -214,9 +214,9 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiún coronas con cero øre'), - (81.25, 'ochenta y un coronas con veinticinco øre'), - (350.90, 'trescientos cincuenta coronas con noventa ø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'), @@ -266,9 +266,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -318,9 +318,9 @@ (2.00, 'dos coronas con cero haléř'), (8.00, 'ocho coronas con cero haléř'), (12.00, 'doce coronas con cero haléř'), - (21.00, 'veintiún coronas con cero haléř'), - (81.25, 'ochenta y un coronas con veinticinco haléř'), - (350.90, 'trescientos cincuenta coronas con noventa 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éř'), @@ -405,13 +405,13 @@ ) TEST_CASES_TO_CURRENCY_TRY = ( - (1.00, 'un lira con cero kuruş'), + (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, 'veintiún liras con cero kuruş'), - (81.25, 'ochenta y un liras con veinticinco kuruş'), - (350.90, 'trescientos cincuenta liras con noventa 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ş'), @@ -708,9 +708,9 @@ (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, 'veintiún libras con cero céntimos'), - (81.25, 'ochenta y un libras con veinticinco céntimos'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -721,9 +721,9 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiún coronas con cero øre'), - (81.25, 'ochenta y un coronas con veinticinco øre'), - (350.90, 'trescientos cincuenta coronas con noventa ø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'), @@ -760,9 +760,10 @@ (2.00, 'dos libras con cero piastras'), (8.00, 'ocho libras con cero piastras'), (12.00, 'doce libras con cero piastras'), - (21.00, 'veintiún libras con cero piastras'), - (81.25, 'ochenta y un libras con veinticinco piastras'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -799,9 +800,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -903,9 +904,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -955,22 +956,22 @@ (2.00, 'dos coronas con cero aurar'), (8.00, 'ocho coronas con cero aurar'), (12.00, 'doce coronas con cero aurar'), - (21.00, 'veintiún coronas con cero aurar'), - (81.25, 'ochenta y un coronas con veinticinco aurar'), - (350.90, 'trescientos cincuenta coronas con noventa 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, 'un lira con cero céntimos'), + (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, 'veintiún liras con cero céntimos'), - (81.25, 'ochenta y un liras con veinticinco céntimos'), - (350.90, 'trescientos cincuenta liras con noventa 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'), @@ -1059,9 +1060,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1241,9 +1242,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1319,9 +1320,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1371,9 +1372,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1462,9 +1463,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1475,9 +1476,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -1488,9 +1489,9 @@ (2.00, 'dos coronas con cero haliers'), (8.00, 'ocho coronas con cero haliers'), (12.00, 'doce coronas con cero haliers'), - (21.00, 'veintiún coronas con cero haliers'), - (81.25, 'ochenta y un coronas con veinticinco haliers'), - (350.90, 'trescientos cincuenta coronas con noventa 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'), @@ -1501,9 +1502,9 @@ (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, 'veintiún leonas con cero céntimos'), - (81.25, 'ochenta y un leonas con veinticinco céntimos'), - (350.90, 'trescientos cincuenta leonas con noventa 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'), From ef69a13084ff62761e47a00ccae1c1729fd131b3 Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:37:53 +0100 Subject: [PATCH 132/340] Improved currency gender handling, now splitting 'dollars' and 'cents' parts on --- num2words/lang_ES.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 5d086d8b..de2d1e13 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -367,7 +367,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', # Source: https://www.rae.es/dpd/una (section 2.2) # split "dollars" part from "cents" part - list_result = result.split(" con ") + list_result = result.split(separator + " ") # "DOLLARS" PART (list_result[0]) @@ -403,6 +403,6 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[1] = list_result[1].replace("uno", "un") # join back "dollars" part with "cents" part - result = " con ".join(list_result) + result = (separator + " ").join(list_result) return result From 4d4ca043f7b3e7f59168ccc765389ced3513f4b7 Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:54:22 +0100 Subject: [PATCH 133/340] Added tests for every currency gender combination (dollars, cents) --- tests/test_es.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_es.py b/tests/test_es.py index e014b811..68a14e0f 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -114,6 +114,7 @@ TEST_CASES_TO_CURRENCY = ( (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'), @@ -125,6 +126,7 @@ TEST_CASES_TO_CURRENCY_ESP = ( (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'), From f89306e32cfe2e4c9d085388519a92f791fd5e2a Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Wed, 3 Aug 2022 14:49:06 -0400 Subject: [PATCH 134/340] Added new release --- CHANGES.rst | 28 ++++++++++++++++++++++++++++ README.rst | 2 +- bin/num2words | 2 +- num2words/lang_KO.py | 2 +- setup.py | 10 +++++++--- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 298f9db9..9f3a7b24 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,34 @@ Changelog ========= +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 ---------------------------- diff --git a/README.rst b/README.rst index 282aef23..9978a20f 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ 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 diff --git a/bin/num2words b/bin/num2words index 02cfc69e..2a20b225 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.10" +__version__ = "0.5.11" __license__ = "LGPL" diff --git a/num2words/lang_KO.py b/num2words/lang_KO.py index e4e01b5b..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("백") diff --git a/setup.py b/setup.py index fbc34f7b..3565f62d 100644 --- a/setup.py +++ b/setup.py @@ -27,8 +27,11 @@ '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.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', @@ -61,11 +64,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', From 2a0148ba4db8ede2b3fe978258edc567a1e06c90 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Thu, 4 Aug 2022 12:10:25 -0400 Subject: [PATCH 135/340] Add new check to base --- tests/test_base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index bd9cbd13..6500db6e 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -58,3 +58,8 @@ def test_is_title(self): self.base.title("one"), "One" ) + self.base.exclude_title.append('one') + self.assertEqual( + self.base.title("one"), + "one" + ) From b8a1d3168ef76a11b8932b4c3cb14e7ed5957d50 Mon Sep 17 00:00:00 2001 From: Katsuya Iida Date: Fri, 20 Aug 2021 17:29:01 +0900 Subject: [PATCH 136/340] =?UTF-8?q?Support=20Japanese=20Reiwa=20(=E4=BB=A4?= =?UTF-8?q?=E5=92=8C/=E3=82=8C=E3=81=84=E3=82=8F)=20era.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_JA.py | 1 + tests/test_ja.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/num2words/lang_JA.py b/num2words/lang_JA.py index 58a29460..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, ("令和", "れいわ")), ] diff --git a/tests/test_ja.py b/tests/test_ja.py index eaac20b7..42da1445 100644 --- a/tests/test_ja.py +++ b/tests/test_ja.py @@ -163,6 +163,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,8 +191,6 @@ 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), "きげんぜんきゅうじゅうくねん") From d741a9d79015f2b009706951791a09c8b89dd478 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Thu, 4 Aug 2022 16:17:58 -0400 Subject: [PATCH 137/340] Update __init__.py remove space --- num2words/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 60400174..1dfb5b06 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -21,7 +21,7 @@ lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, + lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) From 4b13dfddb7dc60821d840dbdf85c0372ba96c1fd Mon Sep 17 00:00:00 2001 From: Gabriel Shekler <46564521+gs202@users.noreply.github.com> Date: Sat, 6 Aug 2022 13:51:57 +0300 Subject: [PATCH 138/340] fix flake issues --- tests/test_he.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/test_he.py b/tests/test_he.py index 688bbf04..2ce6797a 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -89,9 +89,15 @@ def test_pluralize(self): def test_to_currency(self): n = Num2Word_HE() - self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') - self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') - self.assertEqual(n.to_currency(100.50 ,currency='NIS'), 'מאה שקלים וחמישים אגורות') + self.assertEqual( + n.to_currency(20.0, currency='NIS'), 'עשרים שקלים ואפס אגורות' + ) + self.assertEqual( + (n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' + ) + self.assertEqual( + (n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' + ) def test_to_cardinal(self): n = Num2Word_HE() From 55deaa9cbee39498baa9614abc33a7c89fcadc57 Mon Sep 17 00:00:00 2001 From: Gabriel Shekler <46564521+gs202@users.noreply.github.com> Date: Sat, 6 Aug 2022 13:53:14 +0300 Subject: [PATCH 139/340] typo --- tests/test_he.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_he.py b/tests/test_he.py index 2ce6797a..e50a6a22 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -93,10 +93,10 @@ def test_to_currency(self): n.to_currency(20.0, currency='NIS'), 'עשרים שקלים ואפס אגורות' ) self.assertEqual( - (n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' + n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' ) self.assertEqual( - (n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' + n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' ) def test_to_cardinal(self): From ed97e11bfbc8521bffc74ead59927f83d813cfc2 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:19:49 +0300 Subject: [PATCH 140/340] Add Amharic language --- num2words/lang_AM.py | 107 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 num2words/lang_AM.py diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py new file mode 100644 index 00000000..5d1e7bb2 --- /dev/null +++ b/num2words/lang_AM.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from __future__ import division, print_function, unicode_literals + +from . import lang_EU + + +class Num2Word_AM(lang_EU.Num2Word_EU): + def set_high_numwords(self, high): + max = 3 + 3 * len(high) + for word, n in zip(high, range(max, 3, -3)): + self.cards[10 ** n] = word + "ሊዮን" + + def setup(self): + super(Num2Word_AM, self).setup() + + self.negword = "አሉታዊ " + self.pointword = "ነጥብ" + self.exclude_title = ["እና", "ነጥብ", "አሉታዊ"] + + self.mid_numwords = [(1000, "ሺህ"), (100, "መቶ"), (90, "ዘጠና"), + (80, "ሰማኒያ"), (70, "ሰባ"), (60, "ስድሳ"), + (50, "አምሳ"), (40, "አርባ"), (30, "ሠላሳ")] + self.low_numwords = ["ሃያ", "አሥራ ዘጠኝ", "አሥራ ስምንት", "አሥራ ሰባት", + "አስራ ስድስት", "አሥራ አምስት", "አሥራ አራት", "አሥራ ሦስት", + "አሥራ ሁለት", "አሥራ አንድ", "አሥር", "ዘጠኝ", "ስምንት", + "ሰባት", "ስድስት", "አምስት", "አራት", "ሦስት", "ሁለት", + "አንድ", "ዜሮ"] + self.ords = {"አንድ": "አንደኛ", + "ሁለት": "ሁለተኛ", + "ሦስት": "ሦስተኛ", + "አራት": "አራተኛ", + "አምስት": "አምስተኛ", + "ስድስት": "ስድስተኛ", + "ሰባት": "ሰባተኛ", + "ስምንት": "ስምንተኛ", + "ዘጠኝ": "ዘጠነኛ", + "አሥር": "አሥረኛ", + "አሥራ አንድ": "አሥራ አንድ", + "አሥራ ሁለት": "አሥራ ሁለተኛ", + "አሥራ ሦስት": "አሥራ ሦስተኛ", + "አሥራ አራት": "አሥራ አራተኛ", + "አሥራ አምስት": "አሥራ አምስተኛ", + "አሥራ ስድስት": "አሥራ ስድስተኛ", + "አሥራ ሰባት": "አሥራ ሰባተኛ", + "አሥራ ስምንት": "አሥራ ስምንተኛ", + "አሥራ ዘጠኝ": "አሥራ ዘጠነኛ"} + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif 100 > lnum > rnum: + return ("%s-%s" % (ltext, rtext), lnum + rnum) + elif lnum >= 100 > rnum: + return ("%s እና %s" % (ltext, rtext), lnum + rnum) + elif rnum > lnum: + return ("%s %s" % (ltext, rtext), lnum * rnum) + return ("%s, %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + outwords = self.to_cardinal(value).split(" ") + lastwords = outwords[-1].split("-") + lastword = lastwords[-1].lower() + try: + lastword = self.ords[lastword] + except KeyError: + if lastword[-1] == "y": + lastword = lastword[:-1] + "ie" + lastword += "th" + lastwords[-1] = self.title(lastword) + outwords[-1] = "-".join(lastwords) + return " ".join(outwords) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) + + def to_currency(self, val, currency='ብር', cents=True, separator='.', + adjective=False): + result = super(Num2Word_AM, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result + + def to_year(self, val, longval=True): + if not (val // 100) % 10: + return self.to_cardinal(val) + return self.to_splitnum(val, hightxt="መቶ", longval=longval) \ + .replace(' ', '') From c06ff54f6485b67f4d0819be4cf88627eb1ca891 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:30:30 +0300 Subject: [PATCH 141/340] Update init for Amharic language --- num2words/__init__.py | 3 ++- tests/test_am.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/test_am.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 1dfb5b06..baba5bdd 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -23,10 +23,11 @@ lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, - lang_TR, lang_UK, lang_VI) + lang_TR, lang_UK, lang_VI, lang_AM) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), + 'am': lang_AM.Num2Word_AM(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/tests/test_am.py b/tests/test_am.py new file mode 100644 index 00000000..1a8436cf --- /dev/null +++ b/tests/test_am.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsAMTest(TestCase): From 47d63acabf78005bc8d71a853425416047dce2b6 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:34:49 +0300 Subject: [PATCH 142/340] Update Amharic language --- num2words/lang_AM.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 5d1e7bb2..6e4f2f92 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -67,9 +67,9 @@ 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 እና %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) elif rnum > lnum: return ("%s %s" % (ltext, rtext), lnum * rnum) return ("%s, %s" % (ltext, rtext), lnum + rnum) @@ -86,7 +86,7 @@ def to_ordinal(self, value): lastword = lastword[:-1] + "ie" lastword += "th" lastwords[-1] = self.title(lastword) - outwords[-1] = "-".join(lastwords) + outwords[-1] = " ".join(lastwords) return " ".join(outwords) def to_ordinal_num(self, value): From d1a85b315a5401e3313d0023dbe6f19e6b9c5aae Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:02:25 +0300 Subject: [PATCH 143/340] Add Amharic currency form --- num2words/lang_AM.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 6e4f2f92..024e3e1e 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -21,6 +21,8 @@ class Num2Word_AM(lang_EU.Num2Word_EU): + CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + def set_high_numwords(self, high): max = 3 + 3 * len(high) for word, n in zip(high, range(max, 3, -3)): @@ -93,8 +95,8 @@ def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) - def to_currency(self, val, currency='ብር', cents=True, separator='.', - adjective=False): + def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', + adjective=True): result = super(Num2Word_AM, self).to_currency( val, currency=currency, cents=cents, separator=separator, adjective=adjective) From 308965bb993a46138fdf9585bccfa940f295f631 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:06:48 +0300 Subject: [PATCH 144/340] Add test cases --- num2words/lang_AM.py | 3 +-- tests/test_am.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 024e3e1e..40725592 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -105,5 +105,4 @@ def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', def to_year(self, val, longval=True): if not (val // 100) % 10: return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="መቶ", longval=longval) \ - .replace(' ', '') + return self.to_splitnum(val, hightxt="መቶ", longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index 1a8436cf..6c479553 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,3 +21,46 @@ class Num2WordsAMTest(TestCase): + def test_and_join_199(self): + self.assertEqual(num2words(199, lang='am'), "አንድ መቶ ዘጠና ዘጠኝ") + + def test_ordinal(self): + self.assertEqual( + num2words(1, lang='am', to='ordinal'), + 'አንደኛ' + ) + self.assertEqual( + num2words(13, lang='am', to='ordinal'), + 'አሥራ ሦስተኛ' + ) + self.assertEqual( + num2words(22, lang='am', to='ordinal'), + 'ሃያ ሁለተኛ' + ) + + def test_to_currency(self): + self.assertEqual( + num2words('38.4', lang='am', to='currency', cents=False, currency='ETB'), + "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + ) + self.assertEqual( + num2words('0', lang='am', to='currency', separator=' እና', cents=True, currency='ETB'), + "ዜሮ ብር እና ዜሮ ሳንቲም" + ) + + self.assertEqual( + num2words('1.50', lang='am', to='currency', cents=True, currency='ETB'), + "አንድ ብር ከ አምሳ ሳንቲም" + ) + + def test_to_year(self): + self.assertEqual(num2words(1990, lang='am', to='year'), + 'አሥራ ዘጠኝ መቶ ዘጠና') + self.assertEqual(num2words(5555, lang='am', to='year'), + 'አምሳ አምስት መቶ አምሳ አምስት') + self.assertEqual(num2words(2017, lang='am', to='year'), + 'ሁለት ሺህ አሥራ ሰባት') + self.assertEqual(num2words(1066, lang='am', to='year'), + 'አንድ ሺህ ስድሳ ስድስት') + self.assertEqual(num2words(1865, lang='am', to='year'), + 'አሥራ ስምንት መቶ ስድሳ አምስት') From c586bef2d6cdd0e18e8941177674c9ed5ec80c14 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 11:14:40 +0300 Subject: [PATCH 145/340] Fix flake 8 requirements in python3.1 and increase test coverage. --- num2words/__init__.py | 16 ++++++++-------- num2words/lang_AM.py | 2 +- tests/test_am.py | 31 +++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index baba5bdd..dc422200 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,17 +17,17 @@ from __future__ import unicode_literals -from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, - lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, - lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, - lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, - lang_TR, lang_UK, lang_VI, lang_AM) +from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, + lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, + lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, + lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, + lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { - 'ar': lang_AR.Num2Word_AR(), 'am': lang_AM.Num2Word_AM(), + 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 40725592..4e40bda7 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -93,7 +93,7 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + return "%s%s" % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): diff --git a/tests/test_am.py b/tests/test_am.py index 6c479553..a3dc95da 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -38,19 +38,38 @@ def test_ordinal(self): 'ሃያ ሁለተኛ' ) + def test_ordinal_num(self): + self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ') + self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ') + self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ') + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, lang='am'), "አሥራ ሁለት ነጥብ አምስት") + self.assertEqual(num2words(12.51, lang='am'), "አሥራ ሁለት ነጥብ አምስት አንድ") + self.assertEqual(num2words(12.53, lang='am'), "አሥራ ሁለት ነጥብ አምስት ሦስት") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", lang='am') + def test_to_currency(self): self.assertEqual( - num2words('38.4', lang='am', to='currency', cents=False, currency='ETB'), - "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + num2words('38.4', lang='am', to='currency', cents=False, + currency='ETB'), "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" ) self.assertEqual( - num2words('0', lang='am', to='currency', separator=' እና', cents=True, currency='ETB'), - "ዜሮ ብር እና ዜሮ ሳንቲም" + num2words('0', lang='am', to='currency', separator=' እና', + cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" ) self.assertEqual( - num2words('1.50', lang='am', to='currency', cents=True, currency='ETB'), - "አንድ ብር ከ አምሳ ሳንቲም" + num2words('1.50', lang='am', to='currency', cents=True, + currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" ) def test_to_year(self): From c966c983371b665cf294c8804d7cfa58b4b2d451 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Tue, 9 Aug 2022 09:57:58 -0400 Subject: [PATCH 146/340] Fixed flake8 errors --- num2words/lang_TG.py | 1 - tests/test_tg.py | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py index 8a028d58..48291a26 100644 --- a/num2words/lang_TG.py +++ b/num2words/lang_TG.py @@ -147,4 +147,3 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) - diff --git a/tests/test_tg.py b/tests/test_tg.py index 482913be..53a49e4f 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -25,7 +25,7 @@ class Num2WordsTGTest(TestCase): def test_cardinal(self): with self.assertRaises(OverflowError): - num2words(1000000000000000000000000, lang='tg') + num2words(1000000000000000000000000, lang="tg") self.assertEqual(num2words(100, lang="tg"), "сад") self.assertEqual(num2words(100000, lang="tg"), "сад ҳазор") self.assertEqual(num2words(101, lang="tg"), "яксаду як") @@ -63,8 +63,9 @@ def test_to_ordinal(self): 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(136, lang="tg", to="ordinal"), "яксаду сию шашум" + ) self.assertEqual(num2words(500, lang="tg", to="ordinal"), "панҷсадум") self.assertEqual( num2words(1000, lang="tg", to="ordinal"), "як ҳазорум" @@ -100,16 +101,18 @@ def test_to_currency(self): "як ҳазору дусаду сию чор рубл, панҷову шаш копейк", ) self.assertEqual( - num2words(12519.85, lang="tg", to="currency", currency="TJS", - cents=False), + 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ум", - ) \ No newline at end of file + num2words("100", lang="tg", to="ordinal_num"), + "100ум", + ) From 6ea21b82005e0faf5d2fb0b0ae58a80237aa37e8 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 17:00:56 +0300 Subject: [PATCH 147/340] Fix line too long __init__.py --- num2words/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index dc422200..86f1b63a 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, - lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, + lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 75fdd6289f80926d0870206e257436917433b18c Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:13:53 +0300 Subject: [PATCH 148/340] Update Amharic language support --- README.rst | 3 +- num2words/lang_AM.py | 122 ++++++++++++++++++++++++++----------------- tests/test_am.py | 37 +++++++------ 3 files changed, 98 insertions(+), 64 deletions(-) diff --git a/README.rst b/README.rst index 04145315..7b9b487e 100644 --- a/README.rst +++ b/README.rst @@ -76,6 +76,7 @@ Besides the numerical argument, there are two main optional arguments. **lang:** The language in which to convert the number. Supported values are: * ``en`` (English, default) +* ``am`` (Amharic) * ``ar`` (Arabic) * ``cz`` (Czech) * ``de`` (German) @@ -149,4 +150,4 @@ added Lithuanian support, but didn't take over maintenance of the project. I am thus basing myself on Marius Grigaitis' improvements and re-publishing ``pynum2word`` as ``num2words``. -Virgil Dupras, Savoir-faire Linux +Virgil Dupras, Savoir-faire Linux \ No newline at end of file diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 4e40bda7..3efd9c25 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -23,45 +23,73 @@ class Num2Word_AM(lang_EU.Num2Word_EU): CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + GIGA_SUFFIX = 'ቢሊዮን' + MEGA_SUFFIX = 'ሚሊዮን' + def set_high_numwords(self, high): - max = 3 + 3 * len(high) - for word, n in zip(high, range(max, 3, -3)): - self.cards[10 ** n] = word + "ሊዮን" + cap = 3 * (len(high) + 1) + + for word, n in zip(high, range(cap, 5, -3)): + if n == 9: + self.cards[10 ** n] = word + self.GIGA_SUFFIX + else: + self.cards[10 ** n] = word + self.MEGA_SUFFIX def setup(self): super(Num2Word_AM, self).setup() - self.negword = "አሉታዊ " - self.pointword = "ነጥብ" - self.exclude_title = ["እና", "ነጥብ", "አሉታዊ"] - - self.mid_numwords = [(1000, "ሺህ"), (100, "መቶ"), (90, "ዘጠና"), - (80, "ሰማኒያ"), (70, "ሰባ"), (60, "ስድሳ"), - (50, "አምሳ"), (40, "አርባ"), (30, "ሠላሳ")] - self.low_numwords = ["ሃያ", "አሥራ ዘጠኝ", "አሥራ ስምንት", "አሥራ ሰባት", - "አስራ ስድስት", "አሥራ አምስት", "አሥራ አራት", "አሥራ ሦስት", - "አሥራ ሁለት", "አሥራ አንድ", "አሥር", "ዘጠኝ", "ስምንት", - "ሰባት", "ስድስት", "አምስት", "አራት", "ሦስት", "ሁለት", - "አንድ", "ዜሮ"] - self.ords = {"አንድ": "አንደኛ", - "ሁለት": "ሁለተኛ", - "ሦስት": "ሦስተኛ", - "አራት": "አራተኛ", - "አምስት": "አምስተኛ", - "ስድስት": "ስድስተኛ", - "ሰባት": "ሰባተኛ", - "ስምንት": "ስምንተኛ", - "ዘጠኝ": "ዘጠነኛ", - "አሥር": "አሥረኛ", - "አሥራ አንድ": "አሥራ አንድ", - "አሥራ ሁለት": "አሥራ ሁለተኛ", - "አሥራ ሦስት": "አሥራ ሦስተኛ", - "አሥራ አራት": "አሥራ አራተኛ", - "አሥራ አምስት": "አሥራ አምስተኛ", - "አሥራ ስድስት": "አሥራ ስድስተኛ", - "አሥራ ሰባት": "አሥራ ሰባተኛ", - "አሥራ ስምንት": "አሥራ ስምንተኛ", - "አሥራ ዘጠኝ": "አሥራ ዘጠነኛ"} + 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 < 0: + value = abs(value) + out = self.negword + + if value >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) + + if value == 100: + return self.title(out + 'መቶ') + else: + val = self.splitnum(value) + words, num = self.clean(val) + return self.title(out + words) def merge(self, lpair, rpair): ltext, lnum = lpair @@ -69,31 +97,31 @@ 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 %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum + rnum) elif rnum > lnum: - return ("%s %s" % (ltext, rtext), lnum * rnum) - return ("%s, %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum * rnum) + return ('%s, %s' % (ltext, rtext), lnum + rnum) def to_ordinal(self, value): self.verify_ordinal(value) - outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") + outwords = self.to_cardinal(value).split(' ') + lastwords = outwords[-1].split('-') lastword = lastwords[-1].lower() try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == "y": - lastword = lastword[:-1] + "ie" - lastword += "th" + if lastword[-1] == 'y': + lastword = lastword[:-1] + 'ie' + lastword += 'th' lastwords[-1] = self.title(lastword) - outwords[-1] = " ".join(lastwords) - return " ".join(outwords) + outwords[-1] = ' '.join(lastwords) + return ' '.join(outwords) def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-1:]) + return '%s%s' % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): @@ -105,4 +133,4 @@ def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', def to_year(self, val, longval=True): if not (val // 100) % 10: return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="መቶ", longval=longval) + return self.to_splitnum(val, hightxt='መቶ', longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index a3dc95da..460ca6e4 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,10 +21,15 @@ 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'), "አንድ መቶ ዘጠና ዘጠኝ") + self.assertEqual(num2words(199, lang='am'), 'አንድ መቶ ዘጠና ዘጠኝ') - def test_ordinal(self): + def test_to_ordinal(self): self.assertEqual( num2words(1, lang='am', to='ordinal'), 'አንደኛ' @@ -38,38 +43,38 @@ def test_ordinal(self): 'ሃያ ሁለተኛ' ) - def test_ordinal_num(self): + def test_to_ordinal_num(self): self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ') self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ') self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ') def test_cardinal_for_float_number(self): - self.assertEqual(num2words(12.5, lang='am'), "አሥራ ሁለት ነጥብ አምስት") - self.assertEqual(num2words(12.51, lang='am'), "አሥራ ሁለት ነጥብ አምስት አንድ") - self.assertEqual(num2words(12.53, lang='am'), "አሥራ ሁለት ነጥብ አምስት ሦስት") + self.assertEqual(num2words(12.5, lang='am'), 'አሥራ ሁለት ነጥብ አምስት') + self.assertEqual(num2words(12.51, lang='am'), 'አሥራ ሁለት ነጥብ አምስት አንድ') + self.assertEqual(num2words(12.53, lang='am'), 'አሥራ ሁለት ነጥብ አምስት ሦስት') - def test_overflow(self): + def test_to_overflow(self): with self.assertRaises(OverflowError): - num2words("1000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000", lang='am') + num2words('1000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000', lang='am') def test_to_currency(self): self.assertEqual( num2words('38.4', lang='am', to='currency', cents=False, - currency='ETB'), "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + currency='ETB'), 'ሠላሳ ስምንት ብር ከ 40 ሳንቲም' ) self.assertEqual( num2words('0', lang='am', to='currency', separator=' እና', - cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" + cents=True, currency='ETB'), 'ዜሮ ብር እና ዜሮ ሳንቲም' ) self.assertEqual( num2words('1.50', lang='am', to='currency', cents=True, - currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" + currency='ETB'), 'አንድ ብር ከ አምሳ ሳንቲም' ) def test_to_year(self): From b7277ffb93f2421899831dfe3efc53df5467b53e Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:19:56 +0300 Subject: [PATCH 149/340] Update __init__.py --- num2words/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 236f2c7c..3c9171a8 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,15 +17,16 @@ from __future__ import unicode_literals -from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, - lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, - lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, - lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, - lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, + lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, + lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, + lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, + lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, + lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { + 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), From 4c873a6a88e90333c53a753fcf2f520265258bf6 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Wed, 10 Aug 2022 09:34:03 +0300 Subject: [PATCH 150/340] Add additional test case --- num2words/lang_AM.py | 19 ++++++------------- tests/test_am.py | 4 ++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 3efd9c25..77922db3 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -60,7 +60,7 @@ def setup(self): 'ስምንት': 'ስምንተኛ', 'ዘጠኝ': 'ዘጠነኛ', 'አሥር': 'አሥረኛ', - 'አሥራ አንድ': 'አሥራ አንድ', + 'አሥራ አንድ': 'አሥራ አንደኛ', 'አሥራ ሁለት': 'አሥራ ሁለተኛ', 'አሥራ ሦስት': 'አሥራ ሦስተኛ', 'አሥራ አራት': 'አሥራ አራተኛ', @@ -77,10 +77,6 @@ def to_cardinal(self, value): return self.to_cardinal_float(value) out = '' - if value < 0: - value = abs(value) - out = self.negword - if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) @@ -95,14 +91,13 @@ def merge(self, lpair, rpair): ltext, lnum = lpair rtext, rnum = rpair if lnum == 1 and rnum < 100: - return (rtext, rnum) + return rtext, rnum elif 100 > lnum > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif lnum >= 100 > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif rnum > lnum: - return ('%s %s' % (ltext, rtext), lnum * rnum) - return ('%s, %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum * rnum def to_ordinal(self, value): self.verify_ordinal(value) @@ -112,9 +107,7 @@ def to_ordinal(self, value): try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == 'y': - lastword = lastword[:-1] + 'ie' - lastword += 'th' + lastword += 'ኛ' lastwords[-1] = self.title(lastword) outwords[-1] = ' '.join(lastwords) return ' '.join(outwords) diff --git a/tests/test_am.py b/tests/test_am.py index 460ca6e4..58709c37 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -42,6 +42,10 @@ def test_to_ordinal(self): 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ኛ') From 0cde1f6a4ce96920a8b287ea332745d3609270eb Mon Sep 17 00:00:00 2001 From: Mariusz Ryndzionek Date: Sat, 13 Aug 2022 09:04:32 +0200 Subject: [PATCH 151/340] Fixed a typo in PL --- num2words/lang_PL.py | 4 ++-- tests/test_pl.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 1fb1fdcd..c4cfa178 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -80,7 +80,7 @@ 6: ('sześćdziesiąt',), 7: ('siedemdziesiąt',), 8: ('osiemdziesiąt',), - 9: ('dziewięćdzisiąt',), + 9: ('dziewięćdziesiąt',), } TWENTIES_ORDINALS = { @@ -91,7 +91,7 @@ 6: ('sześćdziesiąty', "sześćdziesięcio"), 7: ('siedemdziesiąty', "siedemdziesięcio"), 8: ('osiemdziesiąty', "osiemdziesięcio"), - 9: ('dziewięćdzisiąty', "dziewięćdziesięcio"), + 9: ('dziewięćdziesiąty', "dziewięćdziesięcio"), } HUNDREDS = { diff --git a/tests/test_pl.py b/tests/test_pl.py index 147a747c..cf6e18ad 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -52,7 +52,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'), @@ -62,20 +62,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( From e8425024a6914ab87577b91f09a24d44c8728275 Mon Sep 17 00:00:00 2001 From: Sergio Zanchetta Date: Sun, 16 Jan 2022 00:52:24 +0100 Subject: [PATCH 152/340] Add to_currency and CURRENCY_FORMS for italian --- num2words/lang_IT.py | 119 +++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index 6966d730..d532f7f4 100644 --- a/num2words/lang_IT.py +++ b/num2words/lang_IT.py @@ -16,6 +16,8 @@ from __future__ import unicode_literals +from .lang_EU import Num2Word_EU + # Globals # ------- @@ -43,57 +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" - .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 +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 @@ -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 From 389bfd555df56cd715dbdd6e180e41a93595961c Mon Sep 17 00:00:00 2001 From: Sergio Zanchetta Date: Sun, 16 Jan 2022 12:07:43 +0100 Subject: [PATCH 153/340] Add tests for italian language currencies --- tests/test_it.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/test_it.py b/tests/test_it.py index 348f4ed8..9023355f 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 @@ -240,3 +270,24 @@ def test_with_decimals(self): self.assertAlmostEqual( num2words(1.1, lang="it"), "uno virgola uno" ) + + 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] + ) From e3d53c3ff91dec7543397ec20858cba928e94f01 Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Mon, 9 Nov 2020 18:16:22 +0100 Subject: [PATCH 154/340] fix Polish twenties --- num2words/lang_PL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 1fb1fdcd..ec7e6a22 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -80,7 +80,7 @@ 6: ('sześćdziesiąt',), 7: ('siedemdziesiąt',), 8: ('osiemdziesiąt',), - 9: ('dziewięćdzisiąt',), + 9: ('dziewięćdziesiąt',), } TWENTIES_ORDINALS = { From e239f1a47403faf52d1df82faa2aeda591438154 Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Mon, 9 Nov 2020 18:26:47 +0100 Subject: [PATCH 155/340] adapt polish tests --- tests/test_pl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_pl.py b/tests/test_pl.py index 147a747c..cf6e18ad 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -52,7 +52,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'), @@ -62,20 +62,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( From 3715260bc5994eb61e900f56592046c3681b9977 Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Tue, 16 Aug 2022 14:58:50 +0200 Subject: [PATCH 156/340] increase Polish test coverage --- tests/test_pl.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_pl.py b/tests/test_pl.py index cf6e18ad..08ef0394 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -24,11 +24,13 @@ 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") @@ -94,6 +96,9 @@ def test_to_ordinal(self): 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( @@ -118,6 +123,10 @@ def test_to_ordinal(self): self.assertEqual(num2words(1000000, lang='pl', to='ordinal'), "milionowy") + def test_to_ordinal_error(self): + with self.assertRaises(NotImplementedError): + num2words(1.5, lang='pl', to='ordinal') + def test_currency(self): self.assertEqual( num2words(1.0, lang='pl', to='currency', currency='EUR'), From 8633c0baf2cc5c38cc9caa2c06c1660f15edd824 Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 18:09:07 +0300 Subject: [PATCH 157/340] [FIX] /num2words/lang_TR.py:812:1: W293 blank line contains whitespace --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 59393c29..ee1d6d4c 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -809,7 +809,7 @@ def to_ordinal(self, value): 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: From 3187fa2e055234c8e23cea3eac7405dc9888164a Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 19:11:37 +0300 Subject: [PATCH 158/340] [TEST] ordinal_num test --- tests/test_tr.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_tr.py b/tests/test_tr.py index 84252624..2da70010 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -183,6 +183,10 @@ def test_tr(self): "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ı"} ] for casedata in testcases: From c19ea1314598af17f02dcfacc9fe6b262fd282e6 Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 19:56:11 +0300 Subject: [PATCH 159/340] [TEST] ordinal_num test --- tests/test_tr.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 2da70010..d01ba060 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -182,10 +182,10 @@ def test_tr(self): {"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ü"} + "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ı"} ] From a05f6e5c1d626ddff7f9de0d196ab28915980ffc Mon Sep 17 00:00:00 2001 From: ismail eski Date: Thu, 18 Aug 2022 18:48:10 +0300 Subject: [PATCH 160/340] [FIX] E231 missing whitespace after ',' --- tests/test_tr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index d01ba060..e1aefba5 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -184,9 +184,9 @@ def test_tr(self): {"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": 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ı"} ] for casedata in testcases: From 8db643a918370eec0ef3e2c16b78de42fa9a4999 Mon Sep 17 00:00:00 2001 From: Israel Teixeira Date: Tue, 22 Dec 2020 07:43:10 -0300 Subject: [PATCH 161/340] Remove dupplicated line in lang_PT_BR Remove an unnecessary condition, since the very same action follows it. --- num2words/lang_PT_BR.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 4c73cac3..80eb5e71 100644 --- a/num2words/lang_PT_BR.py +++ b/num2words/lang_PT_BR.py @@ -53,8 +53,6 @@ def merge(self, curr, next): ctext = "cento" if nnum < cnum: - if cnum < 100: - return ("%s e %s" % (ctext, ntext), cnum + nnum) return ("%s e %s" % (ctext, ntext), cnum + nnum) elif (not nnum % 1000000) and cnum > 1: From 9c64d486120fbdc57ceb40f7aca4c61eed40f218 Mon Sep 17 00:00:00 2001 From: Maroua Romdhane Date: Thu, 21 Jan 2021 14:24:38 -0500 Subject: [PATCH 162/340] [UPD] Readme file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index db64202b..c84b491f 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -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 From cb24e20785b0d069fe95421ea398303e2af5b634 Mon Sep 17 00:00:00 2001 From: Israel Teixeira Date: Mon, 25 Jan 2021 22:28:49 -0300 Subject: [PATCH 163/340] This error is already raised in line 223 --- num2words/lang_PT.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/num2words/lang_PT.py b/num2words/lang_PT.py index 6f459726..ddfa7713 100644 --- a/num2words/lang_PT.py +++ b/num2words/lang_PT.py @@ -227,12 +227,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' e', 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', From 1b35e7fe58e55b0222abc970d1fe7c1cf62975a2 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 7 Dec 2020 14:24:51 +0100 Subject: [PATCH 164/340] added swedish language including test cases --- num2words/__init__.py | 3 +- num2words/lang_SV.py | 113 ++++++++++++++++++++++++++++++++++++++++++ tests/test_sv.py | 46 +++++++++++++++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_SV.py create mode 100644 tests/test_sv.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 931d28af..6d40774c 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,7 +22,7 @@ lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { @@ -52,6 +52,7 @@ 'ru': lang_RU.Num2Word_RU(), '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(), diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py new file mode 100644 index 00000000..215c196b --- /dev/null +++ b/num2words/lang_SV.py @@ -0,0 +1,113 @@ +# -*- 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(" ") + lastwords = outwords[-1].split("-") + lastword = lastwords[-1].lower() + try: + lastword = self.ords[lastword] + except KeyError: + if lastword[-2:] == "tio": + lastword = lastword + "onde" + else: + lastword += "de" + lastwords[-1] = self.title(lastword) + outwords[-1] = "".join(lastwords) + return " ".join(outwords) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) + + def to_year(self, val, longval=True): + if not (val // 100) % 10: + return self.to_cardinal(val) + return self.to_splitnum(val, hightxt="hundra", jointxt="och", + longval=longval) + + def to_currency(self, val, longval=True): + return self.to_splitnum(val, hightxt="krone/r", lowtxt="öre/n", + jointxt="och", longval=longval, cents=True) diff --git a/tests/test_sv.py b/tests/test_sv.py new file mode 100644 index 00000000..fa3d48da --- /dev/null +++ b/tests/test_sv.py @@ -0,0 +1,46 @@ +# 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): + pass + self.assertEqual(num2words(1, to="ordinal", lang="sv"), "första") + self.assertEqual(num2words(5, to="ordinal", lang="sv"), "femte") + self.assertEqual(num2words(32, to="ordinal", lang="sv"), "trettioandra") + + + 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(2, to="cardinal", lang="sv"), "två") + self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem") + self.assertEqual(num2words(8, to="cardinal", lang="sv"), "åtta") + self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton") + self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem") + self.assertEqual(num2words(1245, to="cardinal", lang="sv"), "etttusen tvåhundraförtiofem") + self.assertEqual(num2words(4235, to="cardinal", lang="sv"), "fyratusen tvåhundratrettiofem") + self.assertEqual(num2words(1004135, to="cardinal", lang="sv"), "en miljon fyratusen etthundratrettiofem") + self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") + self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") + self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två fem") From a35effbd1b0ccc8016e58c37a682bb06b0076906 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 7 Dec 2020 16:24:58 +0100 Subject: [PATCH 165/340] added correct ordinal handling and more test cases --- num2words/lang_SV.py | 22 +++++++++++++--------- tests/test_sv.py | 6 +++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 215c196b..12ba9ae9 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -85,17 +85,21 @@ def merge(self, lpair, rpair): def to_ordinal(self, value): self.verify_ordinal(value) outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") - lastword = lastwords[-1].lower() + lastword = outwords[-1] + # lastword = lastwords[-1].lower() + ending_length = 0 try: - lastword = self.ords[lastword] - except KeyError: - if lastword[-2:] == "tio": - lastword = lastword + "onde" - else: + lastword_ending = self.ords[lastword[-4:]] + ending_length = 4 + except: + try: + lastword_ending = self.ords[lastword[-3:]] + ending_length = 3 + except KeyError: lastword += "de" - lastwords[-1] = self.title(lastword) - outwords[-1] = "".join(lastwords) + 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): diff --git a/tests/test_sv.py b/tests/test_sv.py index fa3d48da..e4ce4662 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -24,11 +24,11 @@ class Num2WordsSVTest(TestCase): def test_ordinal(self): - pass + 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(32, to="ordinal", lang="sv"), "trettioandra") - + self.assertEqual(num2words(10, to="ordinal", lang="sv"), "tionde") def test_cardinal(self): self.assertEqual(num2words(0, to="cardinal", lang="sv"), "noll") From 469aaff8e6ac499dee2015f09772f3980d0d49c8 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Mon, 25 Jan 2021 14:30:43 +0100 Subject: [PATCH 166/340] updated test case to increase coverage. raised NotImplementedError for options not implemented. --- num2words/lang_SV.py | 20 ++++++++++---------- tests/test_sv.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 12ba9ae9..34a8827c 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -96,22 +96,22 @@ def to_ordinal(self, value): lastword_ending = self.ords[lastword[-3:]] ending_length = 3 except KeyError: - lastword += "de" - lastword_first_part = self.title(lastword)[:-ending_length] + # lastword += "de" + 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): - self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + raise NotImplementedError("'ordinal_num' is not implemented for swedish language") def to_year(self, val, longval=True): - if not (val // 100) % 10: - return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="hundra", jointxt="och", - longval=longval) + raise NotImplementedError("'year' is not implemented for swedish language") + def to_currency(self, val, longval=True): - return self.to_splitnum(val, hightxt="krone/r", lowtxt="öre/n", - jointxt="och", longval=longval, cents=True) + raise NotImplementedError("'currency' is not implemented for swedish language") diff --git a/tests/test_sv.py b/tests/test_sv.py index e4ce4662..fffbd0e0 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -24,6 +24,7 @@ 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") @@ -44,3 +45,17 @@ def test_cardinal(self): self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två 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)) \ No newline at end of file From 3e494d71a0ca618acdbe0aff7ca8efd7a51b80d1 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Tue, 26 Jan 2021 08:40:17 +0100 Subject: [PATCH 167/340] updated failing flake8 test --- num2words/__init__.py | 5 ++--- num2words/lang_SV.py | 4 +--- tests/test_sv.py | 37 +++++++++++++++++++++++-------------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 6d40774c..a8c47370 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, - lang_VI) + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, + lang_UK, lang_VI) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), @@ -68,7 +68,6 @@ 'hu': lang_HU.Num2Word_HU() } - CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index 34a8827c..afdd31ee 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -86,17 +86,15 @@ def to_ordinal(self, value): self.verify_ordinal(value) outwords = self.to_cardinal(value).split(" ") lastword = outwords[-1] - # lastword = lastwords[-1].lower() ending_length = 0 try: lastword_ending = self.ords[lastword[-4:]] ending_length = 4 - except: + except KeyError: try: lastword_ending = self.ords[lastword[-3:]] ending_length = 3 except KeyError: - # lastword += "de" lastword_ending = "de" if lastword_ending == 'de': lastword_first_part = self.title(lastword)[:] diff --git a/tests/test_sv.py b/tests/test_sv.py index fffbd0e0..a780dae2 100644 --- a/tests/test_sv.py +++ b/tests/test_sv.py @@ -25,8 +25,10 @@ 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(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") @@ -34,28 +36,35 @@ def test_ordinal(self): 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(2, to="cardinal", lang="sv"), "två") + self.assertEqual(num2words(3, to="cardinal", lang="sv"), "tre") self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem") - self.assertEqual(num2words(8, to="cardinal", lang="sv"), "åtta") self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton") self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem") - self.assertEqual(num2words(1245, to="cardinal", lang="sv"), "etttusen tvåhundraförtiofem") - self.assertEqual(num2words(4235, to="cardinal", lang="sv"), "fyratusen tvåhundratrettiofem") - self.assertEqual(num2words(1004135, to="cardinal", lang="sv"), "en miljon fyratusen etthundratrettiofem") - self.assertEqual(num2words(14004235000, to="cardinal", lang="sv"), "fjorton miljarder fyra miljoner tvåhundratrettiofemtusen") - self.assertEqual(num2words(14004235, to="cardinal", lang="sv"), "fjorton miljoner fyratusen tvåhundratrettiofem") - self.assertEqual(num2words(1.25, to="cardinal", lang="sv"), "ett komma två fem") + 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)) + 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)) + 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)) \ No newline at end of file + self.assertTrue("'ordinal_num' is not implemented for swedish language" + in str(context.exception)) From 402b1e88e7caabc6d20e94996ef15e15478bc53a Mon Sep 17 00:00:00 2001 From: Fernanda Hernandez Date: Wed, 23 Dec 2020 11:50:06 -0600 Subject: [PATCH 168/340] Add translations to spanish of several currencies --- num2words/lang_ES.py | 191 ++- tests/test_es.py | 2826 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 3014 insertions(+), 3 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index a8cc47de..d6fa77aa 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -21,13 +21,190 @@ from .lang_EU import Num2Word_EU +GENERIC_DOLLARS = ('dolar', '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') + class Num2Word_ES(Num2Word_EU): CURRENCY_FORMS = { 'EUR': (('euro', 'euros'), ('céntimo', 'céntimos')), 'ESP': (('peseta', 'pesetas'), ('céntimo', 'céntimos')), - 'USD': (('dolar', 'dólares'), ('centavo', 'centavos')), + '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'), ('penny', 'pence')), + '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'), ('penny', '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'), ('penny', '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 dolares'), ('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?? @@ -176,4 +353,14 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', 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") + # except in this currencies: leona, corona, + # libra, rupia, lempira, peseta, is 'una' + # but only when it's first word, otherwise + # it's replaced in others words like 'veintiun' + 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 diff --git a/tests/test_es.py b/tests/test_es.py index d306981b..cf3a8c2b 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -124,7 +124,7 @@ ) TEST_CASES_TO_CURRENCY_ESP = ( - (1.00, 'un peseta con cero céntimos'), + (1.00, 'una peseta con cero céntimos'), (2.00, 'dos pesetas con cero céntimos'), (8.00, 'ocho pesetas con cero céntimos'), (12.00, 'doce pesetas con cero céntimos'), @@ -156,6 +156,1661 @@ (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, 'veintiun 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 pence'), + (2.00, 'dos libras con cero pence'), + (8.00, 'ocho libras con cero pence'), + (12.00, 'doce libras con cero pence'), + (21.00, 'veintiun libras con cero pence'), + (81.25, 'ochenta y un libras con veinticinco pence'), + (350.90, 'trescientos cincuenta libras con noventa pence'), + (100.00, 'cien libras con cero pence'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres pence'), +) + +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, 'veintiun 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, 'veintiun coronas con cero öre'), + (81.25, 'ochenta y un coronas con veinticinco öre'), + (350.90, 'trescientos 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, 'veintiun coronas con cero øre'), + (81.25, 'ochenta y un coronas con veinticinco øre'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun coronas con cero haléř'), + (81.25, 'ochenta y un coronas con veinticinco haléř'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'un 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, 'veintiun liras con cero kuruş'), + (81.25, 'ochenta y un liras con veinticinco kuruş'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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 dolar 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero céntimos'), + (81.25, 'ochenta y un libras con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun coronas con cero øre'), + (81.25, 'ochenta y un coronas con veinticinco øre'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero piastras'), + (81.25, 'ochenta y un libras con veinticinco piastras'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun coronas con cero aurar'), + (81.25, 'ochenta y un coronas con veinticinco aurar'), + (350.90, 'trescientos 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, 'un 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, 'veintiun liras con cero céntimos'), + (81.25, 'ochenta y un liras con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero paisas'), + (81.25, 'ochenta y un rupias con veinticinco paisas'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun rupias con cero céntimos'), + (81.25, 'ochenta y un rupias con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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, 'veintiun coronas con cero haliers'), + (81.25, 'ochenta y un coronas con veinticinco haliers'), + (350.90, 'trescientos 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, 'veintiun leonas con cero céntimos'), + (81.25, 'ochenta y un leonas con veinticinco céntimos'), + (350.90, 'trescientos 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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 dolares 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 dolares con cero céntimos'), + (8.00, 'ocho nuevos dolares con cero céntimos'), + (12.00, 'doce nuevos dolares con cero céntimos'), + (21.00, 'veintiun nuevos dolares con cero céntimos'), + (81.25, 'ochenta y un nuevos dolares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta nuevos dolares con noventa céntimos'), + (100.00, 'cien nuevos dolares 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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, 'veintiun 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'), +) + class Num2WordsESTest(TestCase): @@ -204,3 +1859,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='QTQ'), + 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] + ) From 2039df64cff0a36191ac14867ea62dfea6d634c0 Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Wed, 27 Jan 2021 08:09:27 +0100 Subject: [PATCH 169/340] split some lines that were too long for flake8 --- num2words/lang_SV.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py index afdd31ee..4e32841c 100644 --- a/num2words/lang_SV.py +++ b/num2words/lang_SV.py @@ -42,7 +42,7 @@ def setup(self): self.exclude_title = ["och", "komma", "minus"] self.mid_numwords = [(1000, "tusen"), (100, "hundra"), - (90, "nittio"), (80, "\åttio"), (70, "sjuttio"), + (90, "nittio"), (80, "åttio"), (70, "sjuttio"), (60, "sextio"), (50, "femtio"), (40, "förtio"), (30, "trettio")] self.low_numwords = ["tjugo", "nitton", "arton", "sjutton", @@ -105,11 +105,13 @@ def to_ordinal(self, value): return " ".join(outwords) def to_ordinal_num(self, value): - raise NotImplementedError("'ordinal_num' is not implemented for swedish language") + 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") - + 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") + raise NotImplementedError( + "'currency' is not implemented for swedish language") From f1cfc8e41ec37ed7dfdc4d803f8a6e7f588154eb Mon Sep 17 00:00:00 2001 From: Peter Nordstrom Date: Thu, 28 Jan 2021 08:09:56 +0100 Subject: [PATCH 170/340] updated readme (added swedish) --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index c84b491f..ab4cf652 100644 --- a/README.rst +++ b/README.rst @@ -107,6 +107,7 @@ Besides the numerical argument, there are two main optional arguments. * ``pt_BR`` (Portuguese - Brazilian) * ``sl`` (Slovene) * ``sr`` (Serbian) +* ``sv`` (Swedish) * ``ro`` (Romanian) * ``ru`` (Russian) * ``te`` (Telugu) From 5cb46055d794a4dc3effff22af0b4882900b107e Mon Sep 17 00:00:00 2001 From: Erwin de Haan <1627021+EraYaN@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:56:24 +0100 Subject: [PATCH 171/340] Fix ordinal_num output for Dutch (NL) --- num2words/lang_NL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_NL.py b/num2words/lang_NL.py index 8725714c..7251e2ac 100644 --- a/num2words/lang_NL.py +++ b/num2words/lang_NL.py @@ -138,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): """ From ea82fe11ca7c07007b99ba634ffa19429040d621 Mon Sep 17 00:00:00 2001 From: Paulina Komorek <46355739+PaulinaKomorek@users.noreply.github.com> Date: Fri, 23 Apr 2021 21:27:47 +0200 Subject: [PATCH 172/340] [ADD] polish ordinal numbers (#367) --- num2words/lang_PL.py | 94 +++++++++++++++++++++++++++++++++++++++++++- tests/test_pl.py | 29 ++++++++++++-- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 2fa52f79..0f2bd751 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -36,6 +36,28 @@ 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',), @@ -49,6 +71,7 @@ 9: ('dziewiętnaście',), } + TWENTIES = { 2: ('dwadzieścia',), 3: ('trzydzieści',), @@ -60,6 +83,17 @@ 9: ('dziewięćdzisią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ęćdzisiąty', "dziewięćdziesięcio"), +} + HUNDREDS = { 1: ('sto',), 2: ('dwieście',), @@ -72,10 +106,28 @@ 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 @@ -130,8 +182,48 @@ def pluralize(self, n, forms): 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): - raise NotImplementedError() + 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: diff --git a/tests/test_pl.py b/tests/test_pl.py index ec76ed8c..a268c269 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -83,9 +83,32 @@ def test_cardinal(self): ) def test_to_ordinal(self): - # @TODO: implement to_ordinal - with self.assertRaises(NotImplementedError): - num2words(1, lang='pl', to='ordinal') + self.assertEqual(num2words(100, lang='pl', to='ordinal'), "setny") + self.assertEqual( + num2words(101, lang='pl', to='ordinal'), "sto pierwszy") + 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_currency(self): self.assertEqual( From 79a9abfaba0c1bdb0ba07a70010835672afeba35 Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Fri, 7 May 2021 17:05:01 +0200 Subject: [PATCH 173/340] [tr] return Turkish 0 ordinal and cardinal (#347) * [tr] return Turkish 0 ordinal and cardinal * add str_to_number to Turkish * try rather use Num2Word_Base --- num2words/lang_TR.py | 8 +++++++- tests/test_tr.py | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 51f415b9..7fba8711 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -18,8 +18,10 @@ 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" @@ -152,6 +154,8 @@ def to_cardinal(self, value): wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][0], "" ) + if self.integers_to_read[0][0] == "0": + return self.ZERO return wrd if self.total_digits_outside_triplets == 0: @@ -507,6 +511,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: diff --git a/tests/test_tr.py b/tests/test_tr.py index a6fc968a..84252624 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -36,6 +36,7 @@ def test_tr(self): "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"}, @@ -108,6 +109,7 @@ def test_tr(self): "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"}, From 6bf14bee7b8187d99ed8c0f59b6acd3eb0ed648f Mon Sep 17 00:00:00 2001 From: Rostyslav Ivanyk Date: Wed, 30 Jun 2021 20:23:46 +0300 Subject: [PATCH 174/340] Improve Ukrainian support and minor fixes in CZ, KZ, LT, LV, PL, RU, SR languages (#400) * Fix English char 'i' in Ukrainian words * Fix the feminine currency processing for UAH in lang_UK.py * Fix test_ua.py * Fix the feminine currency processing for UAH in lang_RU.py * Add tests for UAH in test_ru.py * Add world currencies to lang_UK.py; Add test cases to test_uk.py for world currencies * Fix incorrect handling of zeros after decimal point for CZ, KZ, LT, LV, PL, RU, SR and UK languages * Add ukrainian ordinal numbers * Fix too long lines of code * Add test for negative cardinal number --- num2words/base.py | 6 +- num2words/lang_CZ.py | 5 +- num2words/lang_KZ.py | 3 +- num2words/lang_LT.py | 5 +- num2words/lang_LV.py | 5 +- num2words/lang_PL.py | 5 +- num2words/lang_RU.py | 10 +- num2words/lang_SR.py | 5 +- num2words/lang_UK.py | 747 ++++++++- tests/test_cz.py | 8 + tests/test_kz.py | 8 + tests/test_lt.py | 8 + tests/test_lv.py | 8 + tests/test_pl.py | 8 + tests/test_ru.py | 65 +- tests/test_sr.py | 8 + tests/test_uk.py | 3438 ++++++++++++++++++++++++++++++++++++++++-- 17 files changed, 4189 insertions(+), 153 deletions(-) diff --git a/num2words/base.py b/num2words/base.py index ccf52482..0929cb93 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -257,6 +257,9 @@ 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) @@ -290,12 +293,13 @@ def to_currency(self, val, currency='EUR', cents=True, separator=',', cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1) minus_str = "%s " % self.negword 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), separator, cents_str, 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_KZ.py b/num2words/lang_KZ.py index 2486325d..67df20ed 100644 --- a/num2words/lang_KZ.py +++ b/num2words/lang_KZ.py @@ -77,10 +77,11 @@ 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, - self._int2word(int(right)) + (ZERO + ' ') * leading_zero_count + self._int2word(int(right)) ) else: return self._int2word(int(n)) 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_PL.py b/num2words/lang_PL.py index 0f2bd751..1fb1fdcd 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -165,10 +165,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_RU.py b/num2words/lang_RU.py index e822d381..8e6c875b 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -144,10 +144,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)) @@ -201,8 +204,11 @@ def to_ordinal(self, number): outwords[-1] = self.title(lastword) return " ".join(outwords).strip() + def _money_verbose(self, number, currency): + return self._int2word(number, currency == 'UAH') + def _cents_verbose(self, number, currency): - return self._int2word(number, currency == 'RUB') + return self._int2word(number, currency in ('UAH', 'RUB')) def _int2word(self, n, feminine=False): if n < 0: diff --git a/num2words/lang_SR.py b/num2words/lang_SR.py index 74ff0f04..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) diff --git a/num2words/lang_UK.py b/num2words/lang_UK.py index 45f87124..a6c0a3bb 100644 --- a/num2words/lang_UK.py +++ b/num2words/lang_UK.py @@ -24,13 +24,13 @@ ONES_FEMININE = { 1: ('одна',), - 2: ('двi',), + 2: ('дві',), 3: ('три',), 4: ('чотири',), 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), + 6: ('шість',), + 7: ('сім',), + 8: ('вісім',), 9: ('дев\'ять',), } @@ -40,12 +40,34 @@ 3: ('три',), 4: ('чотири',), 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), + 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: ('одинадцять',), @@ -53,9 +75,9 @@ 3: ('тринадцять',), 4: ('чотирнадцять',), 5: ('п\'ятнадцять',), - 6: ('шiстнадцять',), - 7: ('сiмнадцять',), - 8: ('вiсiмнадцять',), + 6: ('шістнадцять',), + 7: ('сімнадцять',), + 8: ('вісімнадцять',), 9: ('дев\'ятнадцять',), } @@ -64,61 +86,642 @@ 3: ('тридцять',), 4: ('сорок',), 5: ('п\'ятдесят',), - 6: ('шiстдесят',), - 7: ('сiмдесят',), - 8: ('вiсiмдесят',), + 6: ('шістдесят',), + 7: ('сімдесят',), + 8: ('вісімдесят',), 9: ('дев\'яносто',), } +TWENTIES_ORDINALS = { + 2: ("двадцятий", "двадцяти"), + 3: ("тридцятий", "тридцяти"), + 4: ("сороковий", "сорока"), + 5: ("п'ятдесятий", "п'ятдесяти"), + 6: ("шістдесятий", "шістдесяти"), + 7: ("сімдесятий", "сімдесяти"), + 8: ("вісімдесятий", "вісімдесяти"), + 9: ("дев'яностий", "дев'яности"), +} + HUNDREDS = { 1: ('сто',), - 2: ('двiстi',), + 2: ('двісті',), 3: ('триста',), 4: ('чотириста',), 5: ('п\'ятсот',), - 6: ('шiстсот',), - 7: ('сiмсот',), - 8: ('вiсiмсот',), + 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 + 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 +} + +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): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') - return '%s %s %s' % ( + 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)) @@ -136,7 +739,7 @@ def pluralize(self, n, forms): return forms[form] - def _int2word(self, n, feminine=True): + def _int2word(self, n, feminine=False): if n < 0: return ' '.join([self.negword, self._int2word(abs(n))]) @@ -172,8 +775,78 @@ def _int2word(self, n, feminine=True): 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/tests/test_cz.py b/tests/test_cz.py index 660919b0..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" diff --git a/tests/test_kz.py b/tests/test_kz.py index 68f71f2f..83435640 100644 --- a/tests/test_kz.py +++ b/tests/test_kz.py @@ -44,6 +44,14 @@ 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): 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 754ca621..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") diff --git a/tests/test_pl.py b/tests/test_pl.py index a268c269..147a747c 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -32,6 +32,14 @@ def test_cardinal(self): 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 " diff --git a/tests/test_ru.py b/tests/test_ru.py index f2415aea..dc479758 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -75,6 +75,14 @@ def test_cardinal(self): def test_floating_point(self): self.assertEqual(num2words(5.2, lang='ru'), "пять запятая два") + self.assertEqual( + num2words(10.02, lang='ru'), + "десять запятая ноль два" + ) + self.assertEqual( + num2words(15.007, lang='ru'), + "пятнадцать запятая ноль ноль семь" + ) self.assertEqual( num2words(561.42, lang='ru'), "пятьсот шестьдесят один запятая сорок два" @@ -160,6 +168,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,36 +180,85 @@ 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', 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', 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', separator=' и'), 'сто один рубль и двадцать две копейки' ) self.assertEqual( - num2words(10121, lang='ru', to='currency', currency='EUR', + num2words(10122, lang='ru', to='currency', currency='UAH', separator=' и'), - 'сто один евро и двадцать один цент' + 'сто одна гривна и двадцать две копейки' ) self.assertEqual( num2words(-1251985, lang='ru', to='currency', currency='EUR', cents=False), 'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов' ) + self.assertEqual( + 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'), 'одна тысяча двести тридцать долларов, пятьдесят шесть центов' diff --git a/tests/test_sr.py b/tests/test_sr.py index c97a0930..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') diff --git a/tests/test_uk.py b/tests/test_uk.py index 69342120..84fb770a 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -21,115 +21,3343 @@ 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_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): - 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: + self.assertEqual(num2words(test[0], lang='uk'), 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', - # separator=u' та'), - # "сто один євро та одинадцять центiв" - # ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10122, lang='uk', to='currency', currency='UAH', - separator=u' та'), - "сто одна гривня та двадцять двi копiйки" - ) - # self.assertEqual( - # num2words(10121, lang='uk', to='currency', currency='EUR', - # separator=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', separator=' и', - 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] + ) From b5875b81f7399ec567eb10034172a23c89b8252f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Eski?= Date: Tue, 12 Oct 2021 10:09:49 +0300 Subject: [PATCH 175/340] [ADD] to ordinal number for Turkish --- num2words/lang_TR.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 7fba8711..59393c29 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -806,6 +806,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: From 3b27a09a305fa6c4b461cb01667000e6c584ede5 Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 18:09:07 +0300 Subject: [PATCH 176/340] [FIX] /num2words/lang_TR.py:812:1: W293 blank line contains whitespace --- num2words/lang_TR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 59393c29..ee1d6d4c 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -809,7 +809,7 @@ def to_ordinal(self, value): 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: From 5a8a17d1445943192ec4f16357bd2385763caeb0 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Date: Sat, 19 Mar 2022 19:12:19 -0400 Subject: [PATCH 177/340] feat: ci: replace travis by github workflows --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 20 ------------------ requirements-test.txt | 1 + tox.ini | 19 ++++++++++------- 4 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9bc095e5 --- /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.6, 3.7, 3.8, 3.9, '3.10'] + + 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/.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/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/tox.ini b/tox.ini index 11c8f61b..11cf12a3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,17 @@ [tox] -envlist = flake8,isort,py27,py34,py35,py36,py37 +envlist = py36,py37,py38,py39,py310,flake8,isort + +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: isort, flake8, py310 + [testenv] -passenv = TRAVIS TRAVIS_* +passenv = GITHUB_* deps = coverage delegator.py @@ -25,8 +34,4 @@ deps = isort delegator.py commands = - isort --check-only --recursive --diff num2words tests - -[testenv:py27] -setenv = - PYTHONIOENCODING = UTF-8 + isort --check-only --float-to-top --diff num2words tests From 0b896c5c7d8ec92f57993a050901853c629f6d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:09:55 +0100 Subject: [PATCH 178/340] =?UTF-8?q?Orthography=20fixes:=20added=202=20miss?= =?UTF-8?q?ing=20accents=20(dieciseis->diecis=C3=A9is=20;=20dolar->d=C3=B3?= =?UTF-8?q?lar)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index d6fa77aa..18e6da52 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -21,7 +21,7 @@ from .lang_EU import Num2Word_EU -GENERIC_DOLLARS = ('dolar', 'dólares') +GENERIC_DOLLARS = ('dólar', 'dólares') GENERIC_CENTS = ('centavo', 'centavos') CURRENCIES_UNA = ('SLL', 'SEK', 'NOK', 'CZK', 'DKK', 'ISK', 'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP', @@ -230,7 +230,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", From a61760bd28faf7894933747e3975d7952197b0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:57:46 +0100 Subject: [PATCH 179/340] =?UTF-8?q?Orthography=20fix:=20added=20accent=20v?= =?UTF-8?q?eintiun->veinti=C3=BAn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 1 + 1 file changed, 1 insertion(+) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 18e6da52..6291fd7d 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -363,4 +363,5 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[0] = list_result[0].replace("uno", "una") result = " ".join(list_result) result = result.replace("uno", "un") + result = result.replace("veintiun", "veintiún") # correct orthography for this specific case return result From 1cea15170dfde2e3c1df1e38877cc06707bd3351 Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:03:51 +0100 Subject: [PATCH 180/340] =?UTF-8?q?Orthography=20fixes:=20added=20missing?= =?UTF-8?q?=20accent=20(nuevos=20dolares->nuevos=20d=C3=B3lares);=20fixed?= =?UTF-8?q?=20accents=20in=20test=5Fes.py=20(diecis=C3=A9is,=20d=C3=B3lar,?= =?UTF-8?q?=20d=C3=B3lares,=20veinti=C3=BAn)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_ES.py | 2 +- tests/test_es.py | 282 +++++++++++++++++++++---------------------- 2 files changed, 142 insertions(+), 142 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 6291fd7d..ba22d131 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -184,7 +184,7 @@ class Num2Word_ES(Num2Word_EU): '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 dolares'), ('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')), diff --git a/tests/test_es.py b/tests/test_es.py index cf3a8c2b..da7ff35a 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'), @@ -117,7 +117,7 @@ (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, 'veintiun 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'), @@ -128,18 +128,18 @@ (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, 'veintiun pesetas con cero céntimos'), + (21.00, 'veintiún pesetas con cero céntimos'), (81.25, 'ochenta y un pesetas con veinticinco céntimos'), (350.90, 'trescientos 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'), + (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, 'veintiun 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'), @@ -150,7 +150,7 @@ (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, 'veintiun 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'), @@ -161,7 +161,7 @@ (2.00, 'dos colones con cero centavos'), (8.00, 'ocho colones con cero centavos'), (12.00, 'doce colones con cero centavos'), - (21.00, 'veintiun 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'), @@ -174,7 +174,7 @@ (2.00, 'dos libras con cero pence'), (8.00, 'ocho libras con cero pence'), (12.00, 'doce libras con cero pence'), - (21.00, 'veintiun libras con cero pence'), + (21.00, 'veintiún libras con cero pence'), (81.25, 'ochenta y un libras con veinticinco pence'), (350.90, 'trescientos cincuenta libras con noventa pence'), (100.00, 'cien libras con cero pence'), @@ -187,7 +187,7 @@ (2.00, 'dos rublos con cero kopeykas'), (8.00, 'ocho rublos con cero kopeykas'), (12.00, 'doce rublos con cero kopeykas'), - (21.00, 'veintiun 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'), @@ -200,7 +200,7 @@ (2.00, 'dos coronas con cero öre'), (8.00, 'ocho coronas con cero öre'), (12.00, 'doce coronas con cero öre'), - (21.00, 'veintiun coronas con cero öre'), + (21.00, 'veintiún coronas con cero öre'), (81.25, 'ochenta y un coronas con veinticinco öre'), (350.90, 'trescientos cincuenta coronas con noventa öre'), (100.00, 'cien coronas con cero öre'), @@ -213,7 +213,7 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiun coronas con cero øre'), + (21.00, 'veintiún coronas con cero øre'), (81.25, 'ochenta y un coronas con veinticinco øre'), (350.90, 'trescientos cincuenta coronas con noventa øre'), (100.00, 'cien coronas con cero øre'), @@ -226,7 +226,7 @@ (2.00, 'dos zlotys con cero groszy'), (8.00, 'ocho zlotys con cero groszy'), (12.00, 'doce zlotys con cero groszy'), - (21.00, 'veintiun 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'), @@ -239,7 +239,7 @@ (2.00, 'dos pesos con cero centavos'), (8.00, 'ocho pesos con cero centavos'), (12.00, 'doce pesos con cero centavos'), - (21.00, 'veintiun 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'), @@ -252,7 +252,7 @@ (2.00, 'dos leus con cero bani'), (8.00, 'ocho leus con cero bani'), (12.00, 'doce leus con cero bani'), - (21.00, 'veintiun 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'), @@ -265,7 +265,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -278,7 +278,7 @@ (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, 'veintiun 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'), @@ -291,7 +291,7 @@ (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, 'veintiun 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'), @@ -304,7 +304,7 @@ (2.00, 'dos yuanes con cero jiaos'), (8.00, 'ocho yuanes con cero jiaos'), (12.00, 'doce yuanes con cero jiaos'), - (21.00, 'veintiun 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'), @@ -317,7 +317,7 @@ (2.00, 'dos coronas con cero haléř'), (8.00, 'ocho coronas con cero haléř'), (12.00, 'doce coronas con cero haléř'), - (21.00, 'veintiun coronas con cero haléř'), + (21.00, 'veintiún coronas con cero haléř'), (81.25, 'ochenta y un coronas con veinticinco haléř'), (350.90, 'trescientos cincuenta coronas con noventa haléř'), (100.00, 'cien coronas con cero haléř'), @@ -330,7 +330,7 @@ (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, 'veintiun 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'), @@ -343,7 +343,7 @@ (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, 'veintiun 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'), @@ -356,7 +356,7 @@ (2.00, 'dos reales con cero centavos'), (8.00, 'ocho reales con cero centavos'), (12.00, 'doce reales con cero centavos'), - (21.00, 'veintiun 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'), @@ -369,7 +369,7 @@ (2.00, 'dos yenes con cero sen'), (8.00, 'ocho yenes con cero sen'), (12.00, 'doce yenes con cero sen'), - (21.00, 'veintiun 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'), @@ -382,7 +382,7 @@ (2.00, 'dos wones con cero jeon'), (8.00, 'ocho wones con cero jeon'), (12.00, 'doce wones con cero jeon'), - (21.00, 'veintiun 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'), @@ -395,7 +395,7 @@ (2.00, 'dos wones con cero chon'), (8.00, 'ocho wones con cero chon'), (12.00, 'doce wones con cero chon'), - (21.00, 'veintiun 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'), @@ -408,7 +408,7 @@ (2.00, 'dos liras con cero kuruş'), (8.00, 'ocho liras con cero kuruş'), (12.00, 'doce liras con cero kuruş'), - (21.00, 'veintiun liras con cero kuruş'), + (21.00, 'veintiún liras con cero kuruş'), (81.25, 'ochenta y un liras con veinticinco kuruş'), (350.90, 'trescientos cincuenta liras con noventa kuruş'), (100.00, 'cien liras con cero kuruş'), @@ -421,7 +421,7 @@ (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, 'veintiun 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'), @@ -434,7 +434,7 @@ (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, 'veintiun 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'), @@ -447,7 +447,7 @@ (2.00, 'dos hryvnias con cero kopiykas'), (8.00, 'ocho hryvnias con cero kopiykas'), (12.00, 'doce hryvnias con cero kopiykas'), - (21.00, 'veintiun 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'), @@ -460,7 +460,7 @@ (2.00, 'dos bahts con cero satang'), (8.00, 'ocho bahts con cero satang'), (12.00, 'doce bahts con cero satang'), - (21.00, 'veintiun 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'), @@ -473,7 +473,7 @@ (2.00, 'dos dirhams con cero fils'), (8.00, 'ocho dirhams con cero fils'), (12.00, 'doce dirhams con cero fils'), - (21.00, 'veintiun 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'), @@ -486,7 +486,7 @@ (2.00, 'dos afghanis con cero puls'), (8.00, 'ocho afghanis con cero puls'), (12.00, 'doce afghanis con cero puls'), - (21.00, 'veintiun 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'), @@ -499,7 +499,7 @@ (2.00, 'dos leke con cero qindarka'), (8.00, 'ocho leke con cero qindarka'), (12.00, 'doce leke con cero qindarka'), - (21.00, 'veintiun 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'), @@ -512,7 +512,7 @@ (2.00, 'dos drams con cero lumas'), (8.00, 'ocho drams con cero lumas'), (12.00, 'doce drams con cero lumas'), - (21.00, 'veintiun 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'), @@ -525,7 +525,7 @@ (2.00, 'dos florines con cero centavos'), (8.00, 'ocho florines con cero centavos'), (12.00, 'doce florines con cero centavos'), - (21.00, 'veintiun 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'), @@ -538,7 +538,7 @@ (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, 'veintiun 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'), @@ -551,7 +551,7 @@ (2.00, 'dos florines con cero centavos'), (8.00, 'ocho florines con cero centavos'), (12.00, 'doce florines con cero centavos'), - (21.00, 'veintiun 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'), @@ -564,7 +564,7 @@ (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, 'veintiun 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'), @@ -577,7 +577,7 @@ (2.00, 'dos takas con cero paisas'), (8.00, 'ocho takas con cero paisas'), (12.00, 'doce takas con cero paisas'), - (21.00, 'veintiun 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'), @@ -590,7 +590,7 @@ (2.00, 'dos leva con cero stotinki'), (8.00, 'ocho leva con cero stotinki'), (12.00, 'doce leva con cero stotinki'), - (21.00, 'veintiun 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'), @@ -603,7 +603,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -616,7 +616,7 @@ (2.00, 'dos bolivianos con cero centavos'), (8.00, 'ocho bolivianos con cero centavos'), (12.00, 'doce bolivianos con cero centavos'), - (21.00, 'veintiun 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'), @@ -629,7 +629,7 @@ (2.00, 'dos ngultrum con cero chetrum'), (8.00, 'ocho ngultrum con cero chetrum'), (12.00, 'doce ngultrum con cero chetrum'), - (21.00, 'veintiun 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'), @@ -642,7 +642,7 @@ (2.00, 'dos pulas con cero thebes'), (8.00, 'ocho pulas con cero thebes'), (12.00, 'doce pulas con cero thebes'), - (21.00, 'veintiun 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'), @@ -655,7 +655,7 @@ (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, 'veintiun 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'), @@ -668,7 +668,7 @@ (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, 'veintiun 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'), @@ -677,11 +677,11 @@ ) TEST_CASES_TO_CURRENCY_BZD = ( - (1.00, 'un dolar con cero céntimos'), + (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, 'veintiun 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'), @@ -694,7 +694,7 @@ (2.00, 'dos escudos con cero centavos'), (8.00, 'ocho escudos con cero centavos'), (12.00, 'doce escudos con cero centavos'), - (21.00, 'veintiun 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'), @@ -707,7 +707,7 @@ (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, 'veintiun libras con cero céntimos'), + (21.00, 'veintiún libras con cero céntimos'), (81.25, 'ochenta y un libras con veinticinco céntimos'), (350.90, 'trescientos cincuenta libras con noventa céntimos'), (100.00, 'cien libras con cero céntimos'), @@ -720,7 +720,7 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiun coronas con cero øre'), + (21.00, 'veintiún coronas con cero øre'), (81.25, 'ochenta y un coronas con veinticinco øre'), (350.90, 'trescientos cincuenta coronas con noventa øre'), (100.00, 'cien coronas con cero øre'), @@ -733,7 +733,7 @@ (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, 'veintiun 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'), @@ -746,7 +746,7 @@ (2.00, 'dos sucres con cero centavos'), (8.00, 'ocho sucres con cero centavos'), (12.00, 'doce sucres con cero centavos'), - (21.00, 'veintiun 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'), @@ -759,7 +759,7 @@ (2.00, 'dos libras con cero piastras'), (8.00, 'ocho libras con cero piastras'), (12.00, 'doce libras con cero piastras'), - (21.00, 'veintiun libras con cero piastras'), + (21.00, 'veintiún libras con cero piastras'), (81.25, 'ochenta y un libras con veinticinco piastras'), (350.90, 'trescientos cincuenta libras con noventa piastras'), (100.00, 'cien libras con cero piastras'), @@ -772,7 +772,7 @@ (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, 'veintiun 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'), @@ -785,7 +785,7 @@ (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, 'veintiun 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'), @@ -798,7 +798,7 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiun libras con cero peniques'), + (21.00, 'veintiún libras con cero peniques'), (81.25, 'ochenta y un libras con veinticinco peniques'), (350.90, 'trescientos cincuenta libras con noventa peniques'), (100.00, 'cien libras con cero peniques'), @@ -811,7 +811,7 @@ (2.00, 'dos laris con cero tetris'), (8.00, 'ocho laris con cero tetris'), (12.00, 'doce laris con cero tetris'), - (21.00, 'veintiun 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'), @@ -824,7 +824,7 @@ (2.00, 'dos cedis con cero pesewas'), (8.00, 'ocho cedis con cero pesewas'), (12.00, 'doce cedis con cero pesewas'), - (21.00, 'veintiun 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'), @@ -837,7 +837,7 @@ (2.00, 'dos dalasis con cero bututs'), (8.00, 'ocho dalasis con cero bututs'), (12.00, 'doce dalasis con cero bututs'), - (21.00, 'veintiun 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'), @@ -850,7 +850,7 @@ (2.00, 'dos quetzales con cero centavos'), (8.00, 'ocho quetzales con cero centavos'), (12.00, 'doce quetzales con cero centavos'), - (21.00, 'veintiun 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'), @@ -863,7 +863,7 @@ (2.00, 'dos lempiras con cero centavos'), (8.00, 'ocho lempiras con cero centavos'), (12.00, 'doce lempiras con cero centavos'), - (21.00, 'veintiun 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'), @@ -876,7 +876,7 @@ (2.00, 'dos kunas con cero lipas'), (8.00, 'ocho kunas con cero lipas'), (12.00, 'doce kunas con cero lipas'), - (21.00, 'veintiun 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'), @@ -889,7 +889,7 @@ (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, 'veintiun 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'), @@ -902,7 +902,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -915,7 +915,7 @@ (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, 'veintiun 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'), @@ -928,7 +928,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -941,7 +941,7 @@ (2.00, 'dos riales con cero dinares'), (8.00, 'ocho riales con cero dinares'), (12.00, 'doce riales con cero dinares'), - (21.00, 'veintiun 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'), @@ -954,7 +954,7 @@ (2.00, 'dos coronas con cero aurar'), (8.00, 'ocho coronas con cero aurar'), (12.00, 'doce coronas con cero aurar'), - (21.00, 'veintiun coronas con cero aurar'), + (21.00, 'veintiún coronas con cero aurar'), (81.25, 'ochenta y un coronas con veinticinco aurar'), (350.90, 'trescientos cincuenta coronas con noventa aurar'), (100.00, 'cien coronas con cero aurar'), @@ -967,7 +967,7 @@ (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, 'veintiun liras con cero céntimos'), + (21.00, 'veintiún liras con cero céntimos'), (81.25, 'ochenta y un liras con veinticinco céntimos'), (350.90, 'trescientos cincuenta liras con noventa céntimos'), (100.00, 'cien liras con cero céntimos'), @@ -980,7 +980,7 @@ (2.00, 'dos dinares con cero piastras'), (8.00, 'ocho dinares con cero piastras'), (12.00, 'doce dinares con cero piastras'), - (21.00, 'veintiun 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'), @@ -993,7 +993,7 @@ (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, 'veintiun 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'), @@ -1006,7 +1006,7 @@ (2.00, 'dos som con cero tyiyn'), (8.00, 'ocho som con cero tyiyn'), (12.00, 'doce som con cero tyiyn'), - (21.00, 'veintiun 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'), @@ -1019,7 +1019,7 @@ (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, 'veintiun 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'), @@ -1032,7 +1032,7 @@ (2.00, 'dos dinares con cero fils'), (8.00, 'ocho dinares con cero fils'), (12.00, 'doce dinares con cero fils'), - (21.00, 'veintiun 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'), @@ -1045,7 +1045,7 @@ (2.00, 'dos kips con cero att'), (8.00, 'ocho kips con cero att'), (12.00, 'doce kips con cero att'), - (21.00, 'veintiun 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'), @@ -1058,7 +1058,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1071,7 +1071,7 @@ (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, 'veintiun 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'), @@ -1084,7 +1084,7 @@ (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, 'veintiun 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'), @@ -1097,7 +1097,7 @@ (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, 'veintiun 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'), @@ -1110,7 +1110,7 @@ (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, 'veintiun 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'), @@ -1123,7 +1123,7 @@ (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, 'veintiun 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'), @@ -1136,7 +1136,7 @@ (2.00, 'dos lei con cero bani'), (8.00, 'ocho lei con cero bani'), (12.00, 'doce lei con cero bani'), - (21.00, 'veintiun 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'), @@ -1149,7 +1149,7 @@ (2.00, 'dos ariaris con cero iraimbilanja'), (8.00, 'ocho ariaris con cero iraimbilanja'), (12.00, 'doce ariaris con cero iraimbilanja'), - (21.00, 'veintiun 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'), @@ -1162,7 +1162,7 @@ (2.00, 'dos denares con cero denis'), (8.00, 'ocho denares con cero denis'), (12.00, 'doce denares con cero denis'), - (21.00, 'veintiun 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'), @@ -1175,7 +1175,7 @@ (2.00, 'dos kiats con cero pyas'), (8.00, 'ocho kiats con cero pyas'), (12.00, 'doce kiats con cero pyas'), - (21.00, 'veintiun 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'), @@ -1188,7 +1188,7 @@ (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, 'veintiun 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ö'), @@ -1201,7 +1201,7 @@ (2.00, 'dos patacas con cero avos'), (8.00, 'ocho patacas con cero avos'), (12.00, 'doce patacas con cero avos'), - (21.00, 'veintiun 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'), @@ -1214,7 +1214,7 @@ (2.00, 'dos ouguiyas con cero khoums'), (8.00, 'ocho ouguiyas con cero khoums'), (12.00, 'doce ouguiyas con cero khoums'), - (21.00, 'veintiun 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'), @@ -1227,7 +1227,7 @@ (2.00, 'dos ouguiyas con cero khoums'), (8.00, 'ocho ouguiyas con cero khoums'), (12.00, 'doce ouguiyas con cero khoums'), - (21.00, 'veintiun 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'), @@ -1240,7 +1240,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1253,7 +1253,7 @@ (2.00, 'dos rufiyaas con cero laari'), (8.00, 'ocho rufiyaas con cero laari'), (12.00, 'doce rufiyaas con cero laari'), - (21.00, 'veintiun 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'), @@ -1266,7 +1266,7 @@ (2.00, 'dos kuachas con cero tambalas'), (8.00, 'ocho kuachas con cero tambalas'), (12.00, 'doce kuachas con cero tambalas'), - (21.00, 'veintiun 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'), @@ -1279,7 +1279,7 @@ (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, 'veintiun 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'), @@ -1292,7 +1292,7 @@ (2.00, 'dos metical con cero centavos'), (8.00, 'ocho metical con cero centavos'), (12.00, 'doce metical con cero centavos'), - (21.00, 'veintiun 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'), @@ -1305,7 +1305,7 @@ (2.00, 'dos nairas con cero kobo'), (8.00, 'ocho nairas con cero kobo'), (12.00, 'doce nairas con cero kobo'), - (21.00, 'veintiun 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'), @@ -1318,7 +1318,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -1331,7 +1331,7 @@ (2.00, 'dos riales con cero baisa'), (8.00, 'ocho riales con cero baisa'), (12.00, 'doce riales con cero baisa'), - (21.00, 'veintiun 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'), @@ -1344,7 +1344,7 @@ (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, 'veintiun 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'), @@ -1357,7 +1357,7 @@ (2.00, 'dos kinas con cero toea'), (8.00, 'ocho kinas con cero toea'), (12.00, 'doce kinas con cero toea'), - (21.00, 'veintiun 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'), @@ -1370,7 +1370,7 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiun rupias con cero paisas'), + (21.00, 'veintiún rupias con cero paisas'), (81.25, 'ochenta y un rupias con veinticinco paisas'), (350.90, 'trescientos cincuenta rupias con noventa paisas'), (100.00, 'cien rupias con cero paisas'), @@ -1383,7 +1383,7 @@ (2.00, 'dos zlotys con cero groszy'), (8.00, 'ocho zlotys con cero groszy'), (12.00, 'doce zlotys con cero groszy'), - (21.00, 'veintiun 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'), @@ -1396,7 +1396,7 @@ (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, 'veintiun 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'), @@ -1409,7 +1409,7 @@ (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, 'veintiun 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'), @@ -1422,7 +1422,7 @@ (2.00, 'dos dinares con cero para'), (8.00, 'ocho dinares con cero para'), (12.00, 'doce dinares con cero para'), - (21.00, 'veintiun 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'), @@ -1435,7 +1435,7 @@ (2.00, 'dos rublos con cero kopeks'), (8.00, 'ocho rublos con cero kopeks'), (12.00, 'doce rublos con cero kopeks'), - (21.00, 'veintiun 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'), @@ -1448,7 +1448,7 @@ (2.00, 'dos riales con cero halalas'), (8.00, 'ocho riales con cero halalas'), (12.00, 'doce riales con cero halalas'), - (21.00, 'veintiun 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'), @@ -1461,7 +1461,7 @@ (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, 'veintiun rupias con cero céntimos'), + (21.00, 'veintiún rupias con cero céntimos'), (81.25, 'ochenta y un rupias con veinticinco céntimos'), (350.90, 'trescientos cincuenta rupias con noventa céntimos'), (100.00, 'cien rupias con cero céntimos'), @@ -1474,7 +1474,7 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiun libras con cero peniques'), + (21.00, 'veintiún libras con cero peniques'), (81.25, 'ochenta y un libras con veinticinco peniques'), (350.90, 'trescientos cincuenta libras con noventa peniques'), (100.00, 'cien libras con cero peniques'), @@ -1487,7 +1487,7 @@ (2.00, 'dos coronas con cero haliers'), (8.00, 'ocho coronas con cero haliers'), (12.00, 'doce coronas con cero haliers'), - (21.00, 'veintiun coronas con cero haliers'), + (21.00, 'veintiún coronas con cero haliers'), (81.25, 'ochenta y un coronas con veinticinco haliers'), (350.90, 'trescientos cincuenta coronas con noventa haliers'), (100.00, 'cien coronas con cero haliers'), @@ -1500,7 +1500,7 @@ (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, 'veintiun leonas con cero céntimos'), + (21.00, 'veintiún leonas con cero céntimos'), (81.25, 'ochenta y un leonas con veinticinco céntimos'), (350.90, 'trescientos cincuenta leonas con noventa céntimos'), (100.00, 'cien leonas con cero céntimos'), @@ -1513,7 +1513,7 @@ (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, 'veintiun 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'), @@ -1526,7 +1526,7 @@ (2.00, 'dos colones con cero centavos'), (8.00, 'ocho colones con cero centavos'), (12.00, 'doce colones con cero centavos'), - (21.00, 'veintiun 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'), @@ -1539,7 +1539,7 @@ (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, 'veintiun 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'), @@ -1552,7 +1552,7 @@ (2.00, 'dos somonis con cero dirames'), (8.00, 'ocho somonis con cero dirames'), (12.00, 'doce somonis con cero dirames'), - (21.00, 'veintiun 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'), @@ -1565,7 +1565,7 @@ (2.00, 'dos manat con cero tenge'), (8.00, 'ocho manat con cero tenge'), (12.00, 'doce manat con cero tenge'), - (21.00, 'veintiun 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'), @@ -1578,7 +1578,7 @@ (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, 'veintiun 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'), @@ -1591,7 +1591,7 @@ (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, 'veintiun 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'), @@ -1600,17 +1600,17 @@ ) wordamount = "{} {}".format("cuatro mil ciento cincuenta", - "nuevos dolares con ochenta y tres céntimos") + "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 dolares con cero céntimos'), - (8.00, 'ocho nuevos dolares con cero céntimos'), - (12.00, 'doce nuevos dolares con cero céntimos'), - (21.00, 'veintiun nuevos dolares con cero céntimos'), - (81.25, 'ochenta y un nuevos dolares con veinticinco céntimos'), - (350.90, 'trescientos cincuenta nuevos dolares con noventa céntimos'), - (100.00, 'cien nuevos dolares 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), ) @@ -1619,7 +1619,7 @@ (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, 'veintiun 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'), @@ -1632,7 +1632,7 @@ (2.00, 'dos hryvnias con cero kopiykas'), (8.00, 'ocho hryvnias con cero kopiykas'), (12.00, 'doce hryvnias con cero kopiykas'), - (21.00, 'veintiun 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'), @@ -1645,7 +1645,7 @@ (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, 'veintiun 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'), @@ -1658,7 +1658,7 @@ (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, 'veintiun 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'), @@ -1671,7 +1671,7 @@ (2.00, 'dos sum con cero tiyin'), (8.00, 'ocho sum con cero tiyin'), (12.00, 'doce sum con cero tiyin'), - (21.00, 'veintiun 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'), @@ -1687,7 +1687,7 @@ (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, 'veintiun 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'), @@ -1699,7 +1699,7 @@ (2.00, 'dos dongs con cero xu'), (8.00, 'ocho dongs con cero xu'), (12.00, 'doce dongs con cero xu'), - (21.00, 'veintiun 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'), @@ -1712,7 +1712,7 @@ (2.00, 'dos vatu con cero nenhum'), (8.00, 'ocho vatu con cero nenhum'), (12.00, 'doce vatu con cero nenhum'), - (21.00, 'veintiun 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'), @@ -1725,7 +1725,7 @@ (2.00, 'dos tala con cero centavos'), (8.00, 'ocho tala con cero centavos'), (12.00, 'doce tala con cero centavos'), - (21.00, 'veintiun 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'), @@ -1738,7 +1738,7 @@ (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, 'veintiun 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'), @@ -1751,7 +1751,7 @@ (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, 'veintiun 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'), @@ -1764,7 +1764,7 @@ (2.00, 'dos riales con cero fils'), (8.00, 'ocho riales con cero fils'), (12.00, 'doce riales con cero fils'), - (21.00, 'veintiun 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'), @@ -1777,7 +1777,7 @@ (2.00, 'dos dinares con cero para'), (8.00, 'ocho dinares con cero para'), (12.00, 'doce dinares con cero para'), - (21.00, 'veintiun 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'), @@ -1790,7 +1790,7 @@ (2.00, 'dos kwachas con cero ngwee'), (8.00, 'ocho kwachas con cero ngwee'), (12.00, 'doce kwachas con cero ngwee'), - (21.00, 'veintiun 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'), @@ -1803,7 +1803,7 @@ (2.00, 'dos zaires con cero makuta'), (8.00, 'ocho zaires con cero makuta'), (12.00, 'doce zaires con cero makuta'), - (21.00, 'veintiun 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'), From 4afc68f233c24e59493391f83b5712e7d443744e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Wed, 16 Feb 2022 18:25:37 +0100 Subject: [PATCH 181/340] flake8 fix: fixed comment style Fixed: ./num2words/lang_ES.py:366:56: E261 at least two spaces before inline comment ./num2words/lang_ES.py:366:80: E501 line too long (100 > 79 characters) --- num2words/lang_ES.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index ba22d131..ed66cbe1 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -363,5 +363,6 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[0] = list_result[0].replace("uno", "una") result = " ".join(list_result) result = result.replace("uno", "un") - result = result.replace("veintiun", "veintiún") # correct orthography for this specific case + # correct orthography for the specific case of "veintiún": + result = result.replace("veintiun", "veintiún") return result From fc0c15c4b22d131bee2e7d6c3450cb318475ab30 Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:52:37 +0100 Subject: [PATCH 182/340] Fixed pound cents: penny->penique, pence->peniques; fixed tests accordingly --- num2words/lang_ES.py | 6 +++--- tests/test_es.py | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index ed66cbe1..80a630fa 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -39,7 +39,7 @@ class Num2Word_ES(Num2Word_EU): 'CRC': (('colón', 'colones'), GENERIC_CENTS), 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), - 'GBP': (('libra', 'libras'), ('penny', 'pence')), + 'GBP': (('libra', 'libras'), ('penique', 'peniques')), 'RUB': (('rublo', 'rublos'), ('kopeyka', 'kopeykas')), 'SEK': (('corona', 'coronas'), ('öre', 'öre')), 'NOK': (('corona', 'coronas'), ('øre', 'øre')), @@ -101,7 +101,7 @@ class Num2Word_ES(Num2Word_EU): 'ERN': (('nakfa', 'nakfas'), ('céntimo', 'céntimos')), 'ETB': (('birr', 'birrs'), ('céntimo', 'céntimos')), 'FJD': (GENERIC_DOLLARS, GENERIC_CENTS), - 'FKP': (('libra', 'libras'), ('penny', 'peniques')), + 'FKP': (('libra', 'libras'), ('penique', 'peniques')), 'GEL': (('lari', 'laris'), ('tetri', 'tetris')), 'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')), 'GIP': (('libra', 'libras'), ('penique', 'peniques')), @@ -170,7 +170,7 @@ class Num2Word_ES(Num2Word_EU): 'SCR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), 'SDG': (('libra', 'libras'), ('piastra', 'piastras')), 'SGD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), - 'SHP': (('libra', 'libras'), ('penny', 'peniques')), + 'SHP': (('libra', 'libras'), ('penique', 'peniques')), 'SKK': (('corona', 'coronas'), ('halier', 'haliers')), 'SLL': (('leona', 'leonas'), ('céntimo', 'céntimos')), 'SRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), diff --git a/tests/test_es.py b/tests/test_es.py index da7ff35a..2ac5f124 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -170,16 +170,16 @@ ) TEST_CASES_TO_CURRENCY_GBP = ( - (1.00, 'una libra con cero pence'), - (2.00, 'dos libras con cero pence'), - (8.00, 'ocho libras con cero pence'), - (12.00, 'doce libras con cero pence'), - (21.00, 'veintiún libras con cero pence'), - (81.25, 'ochenta y un libras con veinticinco pence'), - (350.90, 'trescientos cincuenta libras con noventa pence'), - (100.00, 'cien libras con cero pence'), - (4150.83, - 'cuatro mil ciento cincuenta libras con ochenta y tres pence'), + (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, 'veintiún libras con cero peniques'), + (81.25, 'ochenta y un libras con veinticinco peniques'), + (350.90, 'trescientos 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 = ( From 0ee149a4c89c7b432ad62075b35ce89e4e3b1d4e Mon Sep 17 00:00:00 2001 From: gonzy Date: Wed, 16 Feb 2022 18:56:55 +0100 Subject: [PATCH 183/340] Added test covering new fix penny->penique --- tests/test_es.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_es.py b/tests/test_es.py index 2ac5f124..9032354c 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -171,6 +171,7 @@ 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'), From d4c979ea52dfdb94e2252f4bdbd790a399b0a24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al?= <11833677+gonsalet@users.noreply.github.com> Date: Sun, 6 Mar 2022 00:36:40 +0100 Subject: [PATCH 184/340] =?UTF-8?q?Fixed=20accent=20in=20examples=20("cent?= =?UTF-8?q?imos"->"c=C3=A9ntimos")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed accent in Spanish examples ("centimos"->"céntimos"), thus making the example consistent with actual current behaviour. --- bin/num2words | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/num2words b/bin/num2words index 068abf25..02cfc69e 100755 --- a/bin/num2words +++ b/bin/num2words @@ -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 From db5e1d175fedee3240854b0beac2deb88868fc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7al=20Garc=C3=A9s=20D=C3=ADaz-Mun=C3=ADo?= <11833677+gonsalet@users.noreply.github.com> Date: Mon, 21 Mar 2022 16:33:07 +0100 Subject: [PATCH 185/340] Fixed accent in Spanish command line examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed accent in Spanish command line examples ("centimos"->"céntimos"), thus making the example consistent with actual current behaviour. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ab4cf652..282aef23 100644 --- a/README.rst +++ b/README.rst @@ -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:: From 62eba317786396147ded2d9eaa6ac29de573e81b Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Wed, 23 Mar 2022 04:34:52 +0100 Subject: [PATCH 186/340] lang_ES: improved currency gender handling, improved error messages; test_es: updated accordingly --- num2words/lang_ES.py | 70 +++++++++++++++++----- tests/test_es.py | 137 ++++++++++++++++++++++--------------------- 2 files changed, 124 insertions(+), 83 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 80a630fa..5d086d8b 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -27,7 +27,8 @@ 'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP', 'LBP', 'SDG', 'SHP', 'SSP', 'SYP', 'INR', 'IDR', 'LKR', 'MUR', 'NPR', 'PKR', 'SCR', - 'ESP') + 'ESP', 'TRY', 'ITL') +CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP') class Num2Word_ES(Num2Word_EU): @@ -216,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"] @@ -352,17 +357,52 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', result = super(Num2Word_ES, self).to_currency( val, currency=currency, cents=cents, separator=separator, adjective=adjective) - # Handle exception, in spanish is "un euro" and not "uno euro" - # except in this currencies: leona, corona, - # libra, rupia, lempira, peseta, is 'una' - # but only when it's first word, otherwise - # it's replaced in others words like 'veintiun' + # 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(" con ") + + # "DOLLARS" PART (list_result[0]) + + # Feminine currencies ("una libra", "trescientas libras"...) 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") - # correct orthography for the specific case of "veintiún": - result = result.replace("veintiun", "veintiún") + + # "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 = " con ".join(list_result) + return result diff --git a/tests/test_es.py b/tests/test_es.py index 9032354c..e014b811 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -128,9 +128,9 @@ (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, 'veintiún pesetas con cero céntimos'), - (81.25, 'ochenta y un pesetas con veinticinco céntimos'), - (350.90, 'trescientos cincuenta pesetas con noventa 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'), ) @@ -175,9 +175,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -201,9 +201,9 @@ (2.00, 'dos coronas con cero öre'), (8.00, 'ocho coronas con cero öre'), (12.00, 'doce coronas con cero öre'), - (21.00, 'veintiún coronas con cero öre'), - (81.25, 'ochenta y un coronas con veinticinco öre'), - (350.90, 'trescientos cincuenta coronas con noventa ö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'), @@ -214,9 +214,9 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiún coronas con cero øre'), - (81.25, 'ochenta y un coronas con veinticinco øre'), - (350.90, 'trescientos cincuenta coronas con noventa ø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'), @@ -266,9 +266,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -318,9 +318,9 @@ (2.00, 'dos coronas con cero haléř'), (8.00, 'ocho coronas con cero haléř'), (12.00, 'doce coronas con cero haléř'), - (21.00, 'veintiún coronas con cero haléř'), - (81.25, 'ochenta y un coronas con veinticinco haléř'), - (350.90, 'trescientos cincuenta coronas con noventa 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éř'), @@ -405,13 +405,13 @@ ) TEST_CASES_TO_CURRENCY_TRY = ( - (1.00, 'un lira con cero kuruş'), + (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, 'veintiún liras con cero kuruş'), - (81.25, 'ochenta y un liras con veinticinco kuruş'), - (350.90, 'trescientos cincuenta liras con noventa 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ş'), @@ -708,9 +708,9 @@ (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, 'veintiún libras con cero céntimos'), - (81.25, 'ochenta y un libras con veinticinco céntimos'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -721,9 +721,9 @@ (2.00, 'dos coronas con cero øre'), (8.00, 'ocho coronas con cero øre'), (12.00, 'doce coronas con cero øre'), - (21.00, 'veintiún coronas con cero øre'), - (81.25, 'ochenta y un coronas con veinticinco øre'), - (350.90, 'trescientos cincuenta coronas con noventa ø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'), @@ -760,9 +760,10 @@ (2.00, 'dos libras con cero piastras'), (8.00, 'ocho libras con cero piastras'), (12.00, 'doce libras con cero piastras'), - (21.00, 'veintiún libras con cero piastras'), - (81.25, 'ochenta y un libras con veinticinco piastras'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -799,9 +800,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -903,9 +904,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -955,22 +956,22 @@ (2.00, 'dos coronas con cero aurar'), (8.00, 'ocho coronas con cero aurar'), (12.00, 'doce coronas con cero aurar'), - (21.00, 'veintiún coronas con cero aurar'), - (81.25, 'ochenta y un coronas con veinticinco aurar'), - (350.90, 'trescientos cincuenta coronas con noventa 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, 'un lira con cero céntimos'), + (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, 'veintiún liras con cero céntimos'), - (81.25, 'ochenta y un liras con veinticinco céntimos'), - (350.90, 'trescientos cincuenta liras con noventa 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'), @@ -1059,9 +1060,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1241,9 +1242,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1319,9 +1320,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1371,9 +1372,9 @@ (2.00, 'dos rupias con cero paisas'), (8.00, 'ocho rupias con cero paisas'), (12.00, 'doce rupias con cero paisas'), - (21.00, 'veintiún rupias con cero paisas'), - (81.25, 'ochenta y un rupias con veinticinco paisas'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1462,9 +1463,9 @@ (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, 'veintiún rupias con cero céntimos'), - (81.25, 'ochenta y un rupias con veinticinco céntimos'), - (350.90, 'trescientos cincuenta rupias con noventa 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'), @@ -1475,9 +1476,9 @@ (2.00, 'dos libras con cero peniques'), (8.00, 'ocho libras con cero peniques'), (12.00, 'doce libras con cero peniques'), - (21.00, 'veintiún libras con cero peniques'), - (81.25, 'ochenta y un libras con veinticinco peniques'), - (350.90, 'trescientos cincuenta libras con noventa 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'), @@ -1488,9 +1489,9 @@ (2.00, 'dos coronas con cero haliers'), (8.00, 'ocho coronas con cero haliers'), (12.00, 'doce coronas con cero haliers'), - (21.00, 'veintiún coronas con cero haliers'), - (81.25, 'ochenta y un coronas con veinticinco haliers'), - (350.90, 'trescientos cincuenta coronas con noventa 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'), @@ -1501,9 +1502,9 @@ (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, 'veintiún leonas con cero céntimos'), - (81.25, 'ochenta y un leonas con veinticinco céntimos'), - (350.90, 'trescientos cincuenta leonas con noventa 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'), From 12e8402da4138f4bf4ab52cb985d5166518f8a2f Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:37:53 +0100 Subject: [PATCH 187/340] Improved currency gender handling, now splitting 'dollars' and 'cents' parts on --- num2words/lang_ES.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 5d086d8b..de2d1e13 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -367,7 +367,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', # Source: https://www.rae.es/dpd/una (section 2.2) # split "dollars" part from "cents" part - list_result = result.split(" con ") + list_result = result.split(separator + " ") # "DOLLARS" PART (list_result[0]) @@ -403,6 +403,6 @@ def to_currency(self, val, currency='EUR', cents=True, separator=' con', list_result[1] = list_result[1].replace("uno", "un") # join back "dollars" part with "cents" part - result = " con ".join(list_result) + result = (separator + " ").join(list_result) return result From b8a215a9916346f732a0176fc7277b6333a0a77d Mon Sep 17 00:00:00 2001 From: gonzy <11833677+gonsalet@users.noreply.github.com> Date: Thu, 24 Mar 2022 00:54:22 +0100 Subject: [PATCH 188/340] Added tests for every currency gender combination (dollars, cents) --- tests/test_es.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_es.py b/tests/test_es.py index e014b811..68a14e0f 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -114,6 +114,7 @@ TEST_CASES_TO_CURRENCY = ( (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'), @@ -125,6 +126,7 @@ TEST_CASES_TO_CURRENCY_ESP = ( (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'), From 2cb98d3af1097d75e795c0fd67bdd8037d2b5339 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Wed, 3 Aug 2022 14:49:06 -0400 Subject: [PATCH 189/340] Added new release --- CHANGES.rst | 28 ++++++++++++++++++++++++++++ README.rst | 2 +- bin/num2words | 2 +- num2words/lang_KO.py | 2 +- setup.py | 10 +++++++--- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 298f9db9..9f3a7b24 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,34 @@ Changelog ========= +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 ---------------------------- diff --git a/README.rst b/README.rst index 282aef23..9978a20f 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ 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 diff --git a/bin/num2words b/bin/num2words index 02cfc69e..2a20b225 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.10" +__version__ = "0.5.11" __license__ = "LGPL" diff --git a/num2words/lang_KO.py b/num2words/lang_KO.py index e4e01b5b..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("백") diff --git a/setup.py b/setup.py index fbc34f7b..3565f62d 100644 --- a/setup.py +++ b/setup.py @@ -27,8 +27,11 @@ '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.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', @@ -61,11 +64,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', From f2acbc2873bb7791857c77b9836357215d064e15 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Thu, 4 Aug 2022 12:10:25 -0400 Subject: [PATCH 190/340] Add new check to base --- tests/test_base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index bd9cbd13..6500db6e 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -58,3 +58,8 @@ def test_is_title(self): self.base.title("one"), "One" ) + self.base.exclude_title.append('one') + self.assertEqual( + self.base.title("one"), + "one" + ) From 112e91c35a9da5075190fa948dd635515187d230 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:02:49 +0300 Subject: [PATCH 191/340] fix pluralize --- num2words/lang_HE.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 34b2ec8a..2b96dc1b 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -81,11 +81,7 @@ def pluralize(n, forms): - # gettext implementation: - # (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2) - - form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2 - + form = 1 if n == 0 else 0 if n == 1 else 1 return forms[form] @@ -151,6 +147,9 @@ def to_cardinal(self, number): def to_ordinal(self, number): raise NotImplementedError() + def pluralize(self, n, forms): + return pluralize(n, forms) + if __name__ == '__main__': yo = Num2Word_HE() From 07ea1baca273101156cc2fb3c273eb34c502fbe1 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:03:43 +0300 Subject: [PATCH 192/340] implement currency for HE --- num2words/lang_HE.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 2b96dc1b..f9871925 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -136,11 +136,13 @@ def n2w(n): return int2word(int(n)) -def to_currency(n, currency='EUR', cents=True, separator=','): - raise NotImplementedError() - - class Num2Word_HE(Num2Word_Base): + CURRENCY_FORMS = { + 'NIS': (('שקל', 'שקלים'), ('אגורה', 'אגורות')), + 'EUR': (('אירו', 'אירו'), ('סנט', 'סנט')), + 'USD': (('דולר', 'דולרים'), ('סנט', 'סנט')), + } + def to_cardinal(self, number): return n2w(number) @@ -150,6 +152,14 @@ def to_ordinal(self, number): def pluralize(self, n, forms): return pluralize(n, forms) + def to_currency(self, val, currency='NIS', cents=True, separator=' ו', + adjective=False): + result = super(Num2Word_HE, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + # In Hebrew the separator is along with the following word + return result.replace(" ו ", " ו") + if __name__ == '__main__': yo = Num2Word_HE() From f820ee5ec1d92c9196679e8cc966323eeb697956 Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:03:57 +0300 Subject: [PATCH 193/340] add unit tests --- tests/test_he.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_he.py b/tests/test_he.py index 206d7cc5..5a17694e 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -20,6 +20,7 @@ from unittest import TestCase from num2words import num2words +from num2words.lang_HE import Num2Word_HE class Num2WordsHETest(TestCase): @@ -71,3 +72,39 @@ def test_1000_to_9999(self): self.assertEqual( num2words(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים' ) + + def test_pluralize(self): + n = Num2Word_HE() + cr1, cr2 = n.CURRENCY_FORMS['NIS'] + self.assertEqual(n.pluralize(1, cr1), 'שקל') + self.assertEqual(n.pluralize(2, cr1), 'שקלים') + self.assertEqual(n.pluralize(1, cr2), 'אגורה') + self.assertEqual(n.pluralize(2, cr2), 'אגורות') + + cr1, cr2 = n.CURRENCY_FORMS['USD'] + self.assertEqual(n.pluralize(1, cr1), 'דולר') + self.assertEqual(n.pluralize(2, cr1), 'דולרים') + self.assertEqual(n.pluralize(1, cr2), 'סנט') + self.assertEqual(n.pluralize(2, cr2), 'סנט') + + def test_currency_(self): + n = Num2Word_HE() + self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') + self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') + self.assertEqual(n.to_currency(100.50 ,currency='NIS'), 'מאה שקלים וחמישים אגורות') + + def test_to_cardinal(self): + n = Num2Word_HE() + self.assertEqual(n.to_cardinal(1500), u'אלף וחמש מאות') + + +class Num2WordsHETestNotImplementedMethofs(TestCase): + n = Num2Word_HE() + + def test_to_ordinal(self): + with self.assertRaises(NotImplementedError): + self.n.to_ordinal('1') + + def test_large_number(self): + with self.assertRaises(NotImplementedError): + num2words(2000000, lang="he") From 7993ca5023a7a24ef8d2aeed62aa98fa7c59744d Mon Sep 17 00:00:00 2001 From: gshekler Date: Sat, 3 Oct 2020 15:14:21 +0300 Subject: [PATCH 194/340] typo --- tests/test_he.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_he.py b/tests/test_he.py index 5a17694e..688bbf04 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -87,7 +87,7 @@ def test_pluralize(self): self.assertEqual(n.pluralize(1, cr2), 'סנט') self.assertEqual(n.pluralize(2, cr2), 'סנט') - def test_currency_(self): + def test_to_currency(self): n = Num2Word_HE() self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') From c11927b353d111ed6609b57fd9f43e47e6424d54 Mon Sep 17 00:00:00 2001 From: Gabriel Shekler <46564521+gs202@users.noreply.github.com> Date: Sat, 6 Aug 2022 13:51:57 +0300 Subject: [PATCH 195/340] fix flake issues --- tests/test_he.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/test_he.py b/tests/test_he.py index 688bbf04..2ce6797a 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -89,9 +89,15 @@ def test_pluralize(self): def test_to_currency(self): n = Num2Word_HE() - self.assertEqual(n.to_currency(20.0 ,currency='NIS'), 'עשרים שקלים ואפס אגורות') - self.assertEqual(n.to_currency(100.0 ,currency='NIS'), 'מאה שקלים ואפס אגורות') - self.assertEqual(n.to_currency(100.50 ,currency='NIS'), 'מאה שקלים וחמישים אגורות') + self.assertEqual( + n.to_currency(20.0, currency='NIS'), 'עשרים שקלים ואפס אגורות' + ) + self.assertEqual( + (n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' + ) + self.assertEqual( + (n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' + ) def test_to_cardinal(self): n = Num2Word_HE() From b01c44e33cc4bfe75042ca9461adaf556be85b63 Mon Sep 17 00:00:00 2001 From: Gabriel Shekler <46564521+gs202@users.noreply.github.com> Date: Sat, 6 Aug 2022 13:53:14 +0300 Subject: [PATCH 196/340] typo --- tests/test_he.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_he.py b/tests/test_he.py index 2ce6797a..e50a6a22 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -93,10 +93,10 @@ def test_to_currency(self): n.to_currency(20.0, currency='NIS'), 'עשרים שקלים ואפס אגורות' ) self.assertEqual( - (n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' + n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' ) self.assertEqual( - (n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' + n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' ) def test_to_cardinal(self): From 9f59c5c8940f01095c80e94d8c26a0916e110a52 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Wed, 16 Dec 2020 21:11:52 +0330 Subject: [PATCH 197/340] add basic farsi support --- README.rst | 1 + num2words/__init__.py | 3 +- num2words/lang_FA.py | 165 ++++++++++++++++++++++++++++++++++++++++++ tests/test_fa.py | 85 ++++++++++++++++++++++ 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_FA.py create mode 100644 tests/test_fa.py diff --git a/README.rst b/README.rst index 9978a20f..04145315 100644 --- a/README.rst +++ b/README.rst @@ -86,6 +86,7 @@ Besides the numerical argument, there are two main optional arguments. * ``es_CO`` (Spanish - Colombia) * ``es_VE`` (Spanish - Venezuela) * ``eu`` (EURO) +* ``fa`` (Farsi) * ``fi`` (Finnish) * ``fr`` (French) * ``fr_CH`` (French - Switzerland) diff --git a/num2words/__init__.py b/num2words/__init__.py index a8c47370..19090545 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, @@ -30,6 +30,7 @@ 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), + '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(), diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py new file mode 100644 index 00000000..9e232a79 --- /dev/null +++ b/num2words/lang_FA.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. +# Copyright (c) 2018, Abdullah Alhazmy, Alhazmy13. 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 + +import re +from decimal import Decimal +from math import floor + +farsiOnes = [ + "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", + "نه", + "ده", + "یازده", + "دوازده", + "سیزده", + "چهارده", + "پونزده", + "شونزده", + "هیفده", + "هیجده", + "نوزده", +] + +farsiTens = [ + "", + "ده", + "بیست", + "سی", + "چهل", + "پنجاه", + "شصت", + "هفتاد", + "هشتاد", + "نود", +] + +farsiHundreds = [ + "", + "صد", + "دویست", + "سیصد", + "چهارصد", + "پانصد", + "ششصد", + "هفتصد", + "هشتصد", + "نهصد", +] + +farsiBig = [ + '', + ' هزار', + ' میلیون', + " میلیارد", + ' تریلیون', + " تریلیارد", +] + +farsiFrac = ["", "دهم", "صدم"] +farsiFracBig = ["", "هزارم", "میلیونیم", "میلیاردیم"] + +farsiSeperator = ' و ' + +class Num2Word_FA(object): + errmsg_too_big = "Too large" + max_num = 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(math.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 (res == ''): + res = yx + else: + res = yx + farsiSeperator + return res + + def fractional(self, number, l): + if (number == 5): + return "نیم" + x = self.cardinalPos(number) + ld3, lm3 = divmod(l, 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) + + def to_ordinal_num(self, value): + return str(value)+"م" + + def to_cardinal(self, number): + if number < 0: + return "منفی " + self.to_cardinal(-number) + if (number == 0): + return "صفر" + x, y, l = self.float2tuple(number) + if y == 0: + return self.cardinalPos(x) + if x == 0: + return self.fractional(y, l) + return self.cardinalPos(x) + farsiSeperator + self.fractional(y, l) \ No newline at end of file diff --git a/tests/test_fa.py b/tests/test_fa.py new file mode 100644 index 00000000..dbe9574c --- /dev/null +++ b/tests/test_fa.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. +# 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'), "دویست و چهل و دو") + + + + 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") From bbd9de8299aa6d390e2d897c8c7b7cd60142e293 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Sun, 24 Jan 2021 10:10:24 +0330 Subject: [PATCH 198/340] fix test coverage --- num2words/lang_FA.py | 4 +++- tests/test_fa.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index 9e232a79..ca7004ca 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -123,10 +123,12 @@ def cardinalPos(self, number): if (y == 0): continue yx = self.cardinal3(y) + b + if b == ' هزار' and y == 1: + yx = 'هزار' if (res == ''): res = yx else: - res = yx + farsiSeperator + res = yx + farsiSeperator + res return res def fractional(self, number, l): diff --git a/tests/test_fa.py b/tests/test_fa.py index dbe9574c..4082e7f1 100644 --- a/tests/test_fa.py +++ b/tests/test_fa.py @@ -58,8 +58,24 @@ def test_ordinal(self): 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م') From a1f0392beb8f976e1e1e444d2d668600f95b4390 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Sun, 24 Jan 2021 10:30:06 +0330 Subject: [PATCH 199/340] remove unneccery if --- num2words/lang_FA.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index ca7004ca..9c5ff749 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -90,14 +90,7 @@ def float2tuple(self, value): 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(math.floor(post)) + post = int(math.floor(post)) return pre, post, self.precision From 3d2fa184cfbfca6443998a572d1ac8181b2626c7 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Mon, 25 Jan 2021 00:14:05 +0330 Subject: [PATCH 200/340] try fix test failure --- num2words/lang_FA.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index 9c5ff749..f49b5f35 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -90,8 +90,14 @@ def float2tuple(self, value): self.precision = abs(Decimal(str(value)).as_tuple().exponent) post = abs(value - pre) * 10**self.precision - post = int(math.floor(post)) - + 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 From 464f9ed7afd347dcb6b7e71a17fb4deed3138526 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Mon, 25 Jan 2021 10:34:01 +0330 Subject: [PATCH 201/340] fix flake8 problems --- num2words/lang_FA.py | 17 ++++++++--------- tests/test_fa.py | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index f49b5f35..96e9e526 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -17,7 +17,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA -import re from decimal import Decimal from math import floor @@ -76,6 +75,7 @@ farsiSeperator = ' و ' + class Num2Word_FA(object): errmsg_too_big = "Too large" max_num = 10 ** 36 @@ -100,7 +100,6 @@ def float2tuple(self, value): post = int(floor(post)) return pre, post, self.precision - def cardinal3(self, number): if (number < 19): return farsiOnes[number] @@ -108,12 +107,12 @@ def cardinal3(self, number): x, y = divmod(number, 10) if y == 0: return farsiTens[x] - return farsiTens[x] + farsiSeperator + farsiOnes[y] + 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 = '' @@ -130,11 +129,11 @@ def cardinalPos(self, number): res = yx + farsiSeperator + res return res - def fractional(self, number, l): + def fractional(self, number, level): if (number == 5): return "نیم" x = self.cardinalPos(number) - ld3, lm3 = divmod(l, 3) + ld3, lm3 = divmod(level, 3) ltext = (farsiFrac[lm3] + " " + farsiFracBig[ld3]).strip() return x + " " + ltext @@ -158,9 +157,9 @@ def to_cardinal(self, number): return "منفی " + self.to_cardinal(-number) if (number == 0): return "صفر" - x, y, l = self.float2tuple(number) + x, y, level = self.float2tuple(number) if y == 0: return self.cardinalPos(x) if x == 0: - return self.fractional(y, l) - return self.cardinalPos(x) + farsiSeperator + self.fractional(y, l) \ No newline at end of file + return self.fractional(y, level) + return self.cardinalPos(x) + farsiSeperator + self.fractional(y, level) diff --git a/tests/test_fa.py b/tests/test_fa.py index 4082e7f1..9a9c4ead 100644 --- a/tests/test_fa.py +++ b/tests/test_fa.py @@ -62,16 +62,21 @@ def test_cardinal(self): 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'), "هزار و چهارصد") - + 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(1000, lang='fa', to='currency'), 'هزار تومان') self.assertEqual( num2words(1500000, lang='fa', to='currency'), 'یک میلیون و پانصد هزار تومان' @@ -86,9 +91,12 @@ def test_ordinal_num(self): 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(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): From 4e6a5732482d6d17536e2d4d6c91e3f8d867c928 Mon Sep 17 00:00:00 2001 From: Katsuya Iida Date: Fri, 20 Aug 2021 17:29:01 +0900 Subject: [PATCH 202/340] =?UTF-8?q?Support=20Japanese=20Reiwa=20(=E4=BB=A4?= =?UTF-8?q?=E5=92=8C/=E3=82=8C=E3=81=84=E3=82=8F)=20era.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- num2words/lang_JA.py | 1 + tests/test_ja.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/num2words/lang_JA.py b/num2words/lang_JA.py index 58a29460..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, ("令和", "れいわ")), ] diff --git a/tests/test_ja.py b/tests/test_ja.py index eaac20b7..42da1445 100644 --- a/tests/test_ja.py +++ b/tests/test_ja.py @@ -163,6 +163,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,8 +191,6 @@ 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), "きげんぜんきゅうじゅうくねん") From 5d1e3c7d1aaad9e8df0796a547fe0c7ea2fe2c23 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Thu, 4 Aug 2022 16:17:58 -0400 Subject: [PATCH 203/340] Update __init__.py remove space --- num2words/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 19090545..ee54e5cf 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -24,7 +24,7 @@ lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) - + CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), From 16229a31a485e415b8e5c58a3951b7a089dbb1f2 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:19:49 +0300 Subject: [PATCH 204/340] Add Amharic language --- num2words/lang_AM.py | 107 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 num2words/lang_AM.py diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py new file mode 100644 index 00000000..5d1e7bb2 --- /dev/null +++ b/num2words/lang_AM.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from __future__ import division, print_function, unicode_literals + +from . import lang_EU + + +class Num2Word_AM(lang_EU.Num2Word_EU): + def set_high_numwords(self, high): + max = 3 + 3 * len(high) + for word, n in zip(high, range(max, 3, -3)): + self.cards[10 ** n] = word + "ሊዮን" + + def setup(self): + super(Num2Word_AM, self).setup() + + self.negword = "አሉታዊ " + self.pointword = "ነጥብ" + self.exclude_title = ["እና", "ነጥብ", "አሉታዊ"] + + self.mid_numwords = [(1000, "ሺህ"), (100, "መቶ"), (90, "ዘጠና"), + (80, "ሰማኒያ"), (70, "ሰባ"), (60, "ስድሳ"), + (50, "አምሳ"), (40, "አርባ"), (30, "ሠላሳ")] + self.low_numwords = ["ሃያ", "አሥራ ዘጠኝ", "አሥራ ስምንት", "አሥራ ሰባት", + "አስራ ስድስት", "አሥራ አምስት", "አሥራ አራት", "አሥራ ሦስት", + "አሥራ ሁለት", "አሥራ አንድ", "አሥር", "ዘጠኝ", "ስምንት", + "ሰባት", "ስድስት", "አምስት", "አራት", "ሦስት", "ሁለት", + "አንድ", "ዜሮ"] + self.ords = {"አንድ": "አንደኛ", + "ሁለት": "ሁለተኛ", + "ሦስት": "ሦስተኛ", + "አራት": "አራተኛ", + "አምስት": "አምስተኛ", + "ስድስት": "ስድስተኛ", + "ሰባት": "ሰባተኛ", + "ስምንት": "ስምንተኛ", + "ዘጠኝ": "ዘጠነኛ", + "አሥር": "አሥረኛ", + "አሥራ አንድ": "አሥራ አንድ", + "አሥራ ሁለት": "አሥራ ሁለተኛ", + "አሥራ ሦስት": "አሥራ ሦስተኛ", + "አሥራ አራት": "አሥራ አራተኛ", + "አሥራ አምስት": "አሥራ አምስተኛ", + "አሥራ ስድስት": "አሥራ ስድስተኛ", + "አሥራ ሰባት": "አሥራ ሰባተኛ", + "አሥራ ስምንት": "አሥራ ስምንተኛ", + "አሥራ ዘጠኝ": "አሥራ ዘጠነኛ"} + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif 100 > lnum > rnum: + return ("%s-%s" % (ltext, rtext), lnum + rnum) + elif lnum >= 100 > rnum: + return ("%s እና %s" % (ltext, rtext), lnum + rnum) + elif rnum > lnum: + return ("%s %s" % (ltext, rtext), lnum * rnum) + return ("%s, %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + outwords = self.to_cardinal(value).split(" ") + lastwords = outwords[-1].split("-") + lastword = lastwords[-1].lower() + try: + lastword = self.ords[lastword] + except KeyError: + if lastword[-1] == "y": + lastword = lastword[:-1] + "ie" + lastword += "th" + lastwords[-1] = self.title(lastword) + outwords[-1] = "-".join(lastwords) + return " ".join(outwords) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) + + def to_currency(self, val, currency='ብር', cents=True, separator='.', + adjective=False): + result = super(Num2Word_AM, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result + + def to_year(self, val, longval=True): + if not (val // 100) % 10: + return self.to_cardinal(val) + return self.to_splitnum(val, hightxt="መቶ", longval=longval) \ + .replace(' ', '') From 4355e11637359439609528f6c2f201375857b037 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:30:30 +0300 Subject: [PATCH 205/340] Update init for Amharic language --- num2words/__init__.py | 15 ++++++++------- tests/test_am.py | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/test_am.py diff --git a/num2words/__init__.py b/num2words/__init__.py index ee54e5cf..baba5bdd 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,15 +18,16 @@ from __future__ import unicode_literals from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, lang_TR, - lang_UK, lang_VI) - + lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, + lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, + lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, + lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, + lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, + lang_TR, lang_UK, lang_VI, lang_AM) + CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), + 'am': lang_AM.Num2Word_AM(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/tests/test_am.py b/tests/test_am.py new file mode 100644 index 00000000..1a8436cf --- /dev/null +++ b/tests/test_am.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsAMTest(TestCase): From 736db5149e25c3b575c45113c69a7d4dfd3a031a Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:34:49 +0300 Subject: [PATCH 206/340] Update Amharic language --- num2words/lang_AM.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 5d1e7bb2..6e4f2f92 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -67,9 +67,9 @@ 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 እና %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) elif rnum > lnum: return ("%s %s" % (ltext, rtext), lnum * rnum) return ("%s, %s" % (ltext, rtext), lnum + rnum) @@ -86,7 +86,7 @@ def to_ordinal(self, value): lastword = lastword[:-1] + "ie" lastword += "th" lastwords[-1] = self.title(lastword) - outwords[-1] = "-".join(lastwords) + outwords[-1] = " ".join(lastwords) return " ".join(outwords) def to_ordinal_num(self, value): From 770cd6d1d53abbb3c497a8db1e07c9a4e395e6e9 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:02:25 +0300 Subject: [PATCH 207/340] Add Amharic currency form --- num2words/lang_AM.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 6e4f2f92..024e3e1e 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -21,6 +21,8 @@ class Num2Word_AM(lang_EU.Num2Word_EU): + CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + def set_high_numwords(self, high): max = 3 + 3 * len(high) for word, n in zip(high, range(max, 3, -3)): @@ -93,8 +95,8 @@ def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) - def to_currency(self, val, currency='ብር', cents=True, separator='.', - adjective=False): + def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', + adjective=True): result = super(Num2Word_AM, self).to_currency( val, currency=currency, cents=cents, separator=separator, adjective=adjective) From a5a812d4210147a9255a935a2188469b6afa18c7 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:06:48 +0300 Subject: [PATCH 208/340] Add test cases --- num2words/lang_AM.py | 3 +-- tests/test_am.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 024e3e1e..40725592 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -105,5 +105,4 @@ def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', def to_year(self, val, longval=True): if not (val // 100) % 10: return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="መቶ", longval=longval) \ - .replace(' ', '') + return self.to_splitnum(val, hightxt="መቶ", longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index 1a8436cf..6c479553 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,3 +21,46 @@ class Num2WordsAMTest(TestCase): + def test_and_join_199(self): + self.assertEqual(num2words(199, lang='am'), "አንድ መቶ ዘጠና ዘጠኝ") + + def test_ordinal(self): + self.assertEqual( + num2words(1, lang='am', to='ordinal'), + 'አንደኛ' + ) + self.assertEqual( + num2words(13, lang='am', to='ordinal'), + 'አሥራ ሦስተኛ' + ) + self.assertEqual( + num2words(22, lang='am', to='ordinal'), + 'ሃያ ሁለተኛ' + ) + + def test_to_currency(self): + self.assertEqual( + num2words('38.4', lang='am', to='currency', cents=False, currency='ETB'), + "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + ) + self.assertEqual( + num2words('0', lang='am', to='currency', separator=' እና', cents=True, currency='ETB'), + "ዜሮ ብር እና ዜሮ ሳንቲም" + ) + + self.assertEqual( + num2words('1.50', lang='am', to='currency', cents=True, currency='ETB'), + "አንድ ብር ከ አምሳ ሳንቲም" + ) + + def test_to_year(self): + self.assertEqual(num2words(1990, lang='am', to='year'), + 'አሥራ ዘጠኝ መቶ ዘጠና') + self.assertEqual(num2words(5555, lang='am', to='year'), + 'አምሳ አምስት መቶ አምሳ አምስት') + self.assertEqual(num2words(2017, lang='am', to='year'), + 'ሁለት ሺህ አሥራ ሰባት') + self.assertEqual(num2words(1066, lang='am', to='year'), + 'አንድ ሺህ ስድሳ ስድስት') + self.assertEqual(num2words(1865, lang='am', to='year'), + 'አሥራ ስምንት መቶ ስድሳ አምስት') From 5948065b368fa4c21f6f25a9cde5c46d61e7f17a Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 11:14:40 +0300 Subject: [PATCH 209/340] Fix flake 8 requirements in python3.1 and increase test coverage. --- num2words/__init__.py | 16 ++++++++-------- num2words/lang_AM.py | 2 +- tests/test_am.py | 31 +++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index baba5bdd..dc422200 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,17 +17,17 @@ from __future__ import unicode_literals -from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, - lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, - lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, - lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TH, - lang_TR, lang_UK, lang_VI, lang_AM) +from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, + lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, + lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, + lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, + lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { - 'ar': lang_AR.Num2Word_AR(), 'am': lang_AM.Num2Word_AM(), + 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 40725592..4e40bda7 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -93,7 +93,7 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + return "%s%s" % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): diff --git a/tests/test_am.py b/tests/test_am.py index 6c479553..a3dc95da 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -38,19 +38,38 @@ def test_ordinal(self): 'ሃያ ሁለተኛ' ) + def test_ordinal_num(self): + self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ') + self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ') + self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ') + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, lang='am'), "አሥራ ሁለት ነጥብ አምስት") + self.assertEqual(num2words(12.51, lang='am'), "አሥራ ሁለት ነጥብ አምስት አንድ") + self.assertEqual(num2words(12.53, lang='am'), "አሥራ ሁለት ነጥብ አምስት ሦስት") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", lang='am') + def test_to_currency(self): self.assertEqual( - num2words('38.4', lang='am', to='currency', cents=False, currency='ETB'), - "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + num2words('38.4', lang='am', to='currency', cents=False, + currency='ETB'), "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" ) self.assertEqual( - num2words('0', lang='am', to='currency', separator=' እና', cents=True, currency='ETB'), - "ዜሮ ብር እና ዜሮ ሳንቲም" + num2words('0', lang='am', to='currency', separator=' እና', + cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" ) self.assertEqual( - num2words('1.50', lang='am', to='currency', cents=True, currency='ETB'), - "አንድ ብር ከ አምሳ ሳንቲም" + num2words('1.50', lang='am', to='currency', cents=True, + currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" ) def test_to_year(self): From 83203ed98e512765b75ca604a3480a82d513d99f Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 17:00:56 +0300 Subject: [PATCH 210/340] Fix line too long __init__.py --- num2words/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index dc422200..86f1b63a 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, - lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, + lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 8ed54f332d9a2044642b1947ab554cdb52c2f768 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:13:53 +0300 Subject: [PATCH 211/340] Update Amharic language support --- README.rst | 3 +- num2words/lang_AM.py | 122 ++++++++++++++++++++++++++----------------- tests/test_am.py | 37 +++++++------ 3 files changed, 98 insertions(+), 64 deletions(-) diff --git a/README.rst b/README.rst index 04145315..7b9b487e 100644 --- a/README.rst +++ b/README.rst @@ -76,6 +76,7 @@ Besides the numerical argument, there are two main optional arguments. **lang:** The language in which to convert the number. Supported values are: * ``en`` (English, default) +* ``am`` (Amharic) * ``ar`` (Arabic) * ``cz`` (Czech) * ``de`` (German) @@ -149,4 +150,4 @@ added Lithuanian support, but didn't take over maintenance of the project. I am thus basing myself on Marius Grigaitis' improvements and re-publishing ``pynum2word`` as ``num2words``. -Virgil Dupras, Savoir-faire Linux +Virgil Dupras, Savoir-faire Linux \ No newline at end of file diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 4e40bda7..3efd9c25 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -23,45 +23,73 @@ class Num2Word_AM(lang_EU.Num2Word_EU): CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + GIGA_SUFFIX = 'ቢሊዮን' + MEGA_SUFFIX = 'ሚሊዮን' + def set_high_numwords(self, high): - max = 3 + 3 * len(high) - for word, n in zip(high, range(max, 3, -3)): - self.cards[10 ** n] = word + "ሊዮን" + cap = 3 * (len(high) + 1) + + for word, n in zip(high, range(cap, 5, -3)): + if n == 9: + self.cards[10 ** n] = word + self.GIGA_SUFFIX + else: + self.cards[10 ** n] = word + self.MEGA_SUFFIX def setup(self): super(Num2Word_AM, self).setup() - self.negword = "አሉታዊ " - self.pointword = "ነጥብ" - self.exclude_title = ["እና", "ነጥብ", "አሉታዊ"] - - self.mid_numwords = [(1000, "ሺህ"), (100, "መቶ"), (90, "ዘጠና"), - (80, "ሰማኒያ"), (70, "ሰባ"), (60, "ስድሳ"), - (50, "አምሳ"), (40, "አርባ"), (30, "ሠላሳ")] - self.low_numwords = ["ሃያ", "አሥራ ዘጠኝ", "አሥራ ስምንት", "አሥራ ሰባት", - "አስራ ስድስት", "አሥራ አምስት", "አሥራ አራት", "አሥራ ሦስት", - "አሥራ ሁለት", "አሥራ አንድ", "አሥር", "ዘጠኝ", "ስምንት", - "ሰባት", "ስድስት", "አምስት", "አራት", "ሦስት", "ሁለት", - "አንድ", "ዜሮ"] - self.ords = {"አንድ": "አንደኛ", - "ሁለት": "ሁለተኛ", - "ሦስት": "ሦስተኛ", - "አራት": "አራተኛ", - "አምስት": "አምስተኛ", - "ስድስት": "ስድስተኛ", - "ሰባት": "ሰባተኛ", - "ስምንት": "ስምንተኛ", - "ዘጠኝ": "ዘጠነኛ", - "አሥር": "አሥረኛ", - "አሥራ አንድ": "አሥራ አንድ", - "አሥራ ሁለት": "አሥራ ሁለተኛ", - "አሥራ ሦስት": "አሥራ ሦስተኛ", - "አሥራ አራት": "አሥራ አራተኛ", - "አሥራ አምስት": "አሥራ አምስተኛ", - "አሥራ ስድስት": "አሥራ ስድስተኛ", - "አሥራ ሰባት": "አሥራ ሰባተኛ", - "አሥራ ስምንት": "አሥራ ስምንተኛ", - "አሥራ ዘጠኝ": "አሥራ ዘጠነኛ"} + 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 < 0: + value = abs(value) + out = self.negword + + if value >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) + + if value == 100: + return self.title(out + 'መቶ') + else: + val = self.splitnum(value) + words, num = self.clean(val) + return self.title(out + words) def merge(self, lpair, rpair): ltext, lnum = lpair @@ -69,31 +97,31 @@ 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 %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum + rnum) elif rnum > lnum: - return ("%s %s" % (ltext, rtext), lnum * rnum) - return ("%s, %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum * rnum) + return ('%s, %s' % (ltext, rtext), lnum + rnum) def to_ordinal(self, value): self.verify_ordinal(value) - outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") + outwords = self.to_cardinal(value).split(' ') + lastwords = outwords[-1].split('-') lastword = lastwords[-1].lower() try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == "y": - lastword = lastword[:-1] + "ie" - lastword += "th" + if lastword[-1] == 'y': + lastword = lastword[:-1] + 'ie' + lastword += 'th' lastwords[-1] = self.title(lastword) - outwords[-1] = " ".join(lastwords) - return " ".join(outwords) + outwords[-1] = ' '.join(lastwords) + return ' '.join(outwords) def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-1:]) + return '%s%s' % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): @@ -105,4 +133,4 @@ def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', def to_year(self, val, longval=True): if not (val // 100) % 10: return self.to_cardinal(val) - return self.to_splitnum(val, hightxt="መቶ", longval=longval) + return self.to_splitnum(val, hightxt='መቶ', longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index a3dc95da..460ca6e4 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,10 +21,15 @@ 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'), "አንድ መቶ ዘጠና ዘጠኝ") + self.assertEqual(num2words(199, lang='am'), 'አንድ መቶ ዘጠና ዘጠኝ') - def test_ordinal(self): + def test_to_ordinal(self): self.assertEqual( num2words(1, lang='am', to='ordinal'), 'አንደኛ' @@ -38,38 +43,38 @@ def test_ordinal(self): 'ሃያ ሁለተኛ' ) - def test_ordinal_num(self): + def test_to_ordinal_num(self): self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ') self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ') self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ') def test_cardinal_for_float_number(self): - self.assertEqual(num2words(12.5, lang='am'), "አሥራ ሁለት ነጥብ አምስት") - self.assertEqual(num2words(12.51, lang='am'), "አሥራ ሁለት ነጥብ አምስት አንድ") - self.assertEqual(num2words(12.53, lang='am'), "አሥራ ሁለት ነጥብ አምስት ሦስት") + self.assertEqual(num2words(12.5, lang='am'), 'አሥራ ሁለት ነጥብ አምስት') + self.assertEqual(num2words(12.51, lang='am'), 'አሥራ ሁለት ነጥብ አምስት አንድ') + self.assertEqual(num2words(12.53, lang='am'), 'አሥራ ሁለት ነጥብ አምስት ሦስት') - def test_overflow(self): + def test_to_overflow(self): with self.assertRaises(OverflowError): - num2words("1000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000", lang='am') + num2words('1000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000', lang='am') def test_to_currency(self): self.assertEqual( num2words('38.4', lang='am', to='currency', cents=False, - currency='ETB'), "ሠላሳ ስምንት ብር ከ 40 ሳንቲም" + currency='ETB'), 'ሠላሳ ስምንት ብር ከ 40 ሳንቲም' ) self.assertEqual( num2words('0', lang='am', to='currency', separator=' እና', - cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" + cents=True, currency='ETB'), 'ዜሮ ብር እና ዜሮ ሳንቲም' ) self.assertEqual( num2words('1.50', lang='am', to='currency', cents=True, - currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" + currency='ETB'), 'አንድ ብር ከ አምሳ ሳንቲም' ) def test_to_year(self): From 5bfcebd9fb32bb2c6b946e4270624aa4045bfe11 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 17:00:13 +0500 Subject: [PATCH 212/340] Added Tajik language support --- README.rst | 1 + num2words/__init__.py | 1 + num2words/lang_TG.py | 149 ++++++++++++++++++++++++++++++++++++++++++ tests/test_tg.py | 104 +++++++++++++++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 num2words/lang_TG.py create mode 100644 tests/test_tg.py diff --git a/README.rst b/README.rst index 7b9b487e..2a8f99f4 100644 --- a/README.rst +++ b/README.rst @@ -113,6 +113,7 @@ Besides the numerical argument, there are two main optional arguments. * ``ro`` (Romanian) * ``ru`` (Russian) * ``te`` (Telugu) +* ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) * ``vi`` (Vietnamese) diff --git a/num2words/__init__.py b/num2words/__init__.py index 86f1b63a..1bc70943 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -62,6 +62,7 @@ '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(), diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py new file mode 100644 index 00000000..cc0bf497 --- /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 + + elif self.MEGA_SUFFIX: + 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/tests/test_tg.py b/tests/test_tg.py new file mode 100644 index 00000000..2caa9cf1 --- /dev/null +++ b/tests/test_tg.py @@ -0,0 +1,104 @@ +# -*- 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): + self.assertEqual(num2words(100, 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(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"), + "як ҳазору дусаду си доллар, панҷову шаш сент", + ) \ No newline at end of file From af97683fdc972e262e6f5b5c0e95059b2a19d156 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 18:51:22 +0500 Subject: [PATCH 213/340] Added test for OverflowError and ordinal_num --- tests/test_tg.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_tg.py b/tests/test_tg.py index 2caa9cf1..a846d701 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -24,7 +24,10 @@ 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"), "яксаду понздаҳ") @@ -101,4 +104,9 @@ def test_to_currency(self): 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ум", ) \ No newline at end of file From beb3326bbca5fbf3a28404567c71a5151bcf996d Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Fri, 2 Jul 2021 22:29:28 +0500 Subject: [PATCH 214/340] Added MEGA_SUFFIX and GIGA_SUFFIX tests --- num2words/lang_TG.py | 3 ++- tests/test_tg.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py index cc0bf497..8a028d58 100644 --- a/num2words/lang_TG.py +++ b/num2words/lang_TG.py @@ -43,7 +43,7 @@ def set_high_numwords(self, high): if n == 9: self.cards[10 ** n] = word + self.GIGA_SUFFIX - elif self.MEGA_SUFFIX: + else: self.cards[10 ** n] = word + self.MEGA_SUFFIX def setup(self): @@ -147,3 +147,4 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) + diff --git a/tests/test_tg.py b/tests/test_tg.py index a846d701..482913be 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -45,6 +45,9 @@ def test_cardinal(self): "як миллиарду дусаду сию чор миллиону панҷсаду шасту ҳафт ҳазору " "ҳаштсаду навад", ) + 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"), "минус понздаҳ") From 7bf80d5dd73cf6f2b228cc5cd2258cd0bc02d235 Mon Sep 17 00:00:00 2001 From: Drew Echerd Date: Tue, 9 Aug 2022 09:57:58 -0400 Subject: [PATCH 215/340] Fixed flake8 errors --- num2words/lang_TG.py | 1 - tests/test_tg.py | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py index 8a028d58..48291a26 100644 --- a/num2words/lang_TG.py +++ b/num2words/lang_TG.py @@ -147,4 +147,3 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) - diff --git a/tests/test_tg.py b/tests/test_tg.py index 482913be..53a49e4f 100644 --- a/tests/test_tg.py +++ b/tests/test_tg.py @@ -25,7 +25,7 @@ class Num2WordsTGTest(TestCase): def test_cardinal(self): with self.assertRaises(OverflowError): - num2words(1000000000000000000000000, lang='tg') + num2words(1000000000000000000000000, lang="tg") self.assertEqual(num2words(100, lang="tg"), "сад") self.assertEqual(num2words(100000, lang="tg"), "сад ҳазор") self.assertEqual(num2words(101, lang="tg"), "яксаду як") @@ -63,8 +63,9 @@ def test_to_ordinal(self): 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(136, lang="tg", to="ordinal"), "яксаду сию шашум" + ) self.assertEqual(num2words(500, lang="tg", to="ordinal"), "панҷсадум") self.assertEqual( num2words(1000, lang="tg", to="ordinal"), "як ҳазорум" @@ -100,16 +101,18 @@ def test_to_currency(self): "як ҳазору дусаду сию чор рубл, панҷову шаш копейк", ) self.assertEqual( - num2words(12519.85, lang="tg", to="currency", currency="TJS", - cents=False), + 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ум", - ) \ No newline at end of file + num2words("100", lang="tg", to="ordinal_num"), + "100ум", + ) From a7442708fabe210555356fb4c0ac9fc7ae9a92ff Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:19:56 +0300 Subject: [PATCH 216/340] Update __init__.py --- num2words/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 1bc70943..3c9171a8 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -23,7 +23,7 @@ lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, - lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) + lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 2ca98971e1d51e3449e32314ca0342e5776506d4 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Wed, 10 Aug 2022 09:34:03 +0300 Subject: [PATCH 217/340] Add additional test case --- num2words/lang_AM.py | 19 ++++++------------- tests/test_am.py | 4 ++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 3efd9c25..77922db3 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -60,7 +60,7 @@ def setup(self): 'ስምንት': 'ስምንተኛ', 'ዘጠኝ': 'ዘጠነኛ', 'አሥር': 'አሥረኛ', - 'አሥራ አንድ': 'አሥራ አንድ', + 'አሥራ አንድ': 'አሥራ አንደኛ', 'አሥራ ሁለት': 'አሥራ ሁለተኛ', 'አሥራ ሦስት': 'አሥራ ሦስተኛ', 'አሥራ አራት': 'አሥራ አራተኛ', @@ -77,10 +77,6 @@ def to_cardinal(self, value): return self.to_cardinal_float(value) out = '' - if value < 0: - value = abs(value) - out = self.negword - if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) @@ -95,14 +91,13 @@ def merge(self, lpair, rpair): ltext, lnum = lpair rtext, rnum = rpair if lnum == 1 and rnum < 100: - return (rtext, rnum) + return rtext, rnum elif 100 > lnum > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif lnum >= 100 > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif rnum > lnum: - return ('%s %s' % (ltext, rtext), lnum * rnum) - return ('%s, %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum * rnum def to_ordinal(self, value): self.verify_ordinal(value) @@ -112,9 +107,7 @@ def to_ordinal(self, value): try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == 'y': - lastword = lastword[:-1] + 'ie' - lastword += 'th' + lastword += 'ኛ' lastwords[-1] = self.title(lastword) outwords[-1] = ' '.join(lastwords) return ' '.join(outwords) diff --git a/tests/test_am.py b/tests/test_am.py index 460ca6e4..58709c37 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -42,6 +42,10 @@ def test_to_ordinal(self): 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ኛ') From 084ace67cbffa193857ef4bed73290b598a63f4c Mon Sep 17 00:00:00 2001 From: "potapov.s" Date: Tue, 2 Nov 2021 12:59:24 +0300 Subject: [PATCH 218/340] - add uzs for ru and en --- num2words/lang_EU.py | 6 ++++-- num2words/lang_RU.py | 3 +++ tests/test_en.py | 6 ++++++ tests/test_ru.py | 5 +++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 09d39c15..529547a9 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -43,7 +43,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), - 'HUF': (('forint', 'forint'), ('fillér', 'fillér')) + 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), + 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')) } CURRENCY_ADJECTIVES = { @@ -56,7 +57,8 @@ class Num2Word_EU(Num2Word_Base): 'MXN': 'Mexican', 'RON': 'Romanian', 'INR': 'Indian', - 'HUF': 'Hungarian' + 'HUF': 'Hungarian', + 'UZS': 'Uzbekistan' } GIGA_SUFFIX = "illiard" diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 8e6c875b..166169c2 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -113,6 +113,9 @@ class Num2Word_RU(Num2Word_Base): 'KZT': ( ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') ), + 'UZS': ( + ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') + ), } def setup(self): diff --git a/tests/test_en.py b/tests/test_en.py index 6234ac98..e763841c 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -131,6 +131,12 @@ def test_to_currency(self): "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_ru.py b/tests/test_ru.py index dc479758..85d6dc3e 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -272,3 +272,8 @@ def test_to_currency(self): 'одна тысяча двести тридцать четыре доллара, пятьдесят шесть ' 'центов' ) + self.assertEqual( + num2words(10122, lang='ru', to='currency', currency='UZS', + separator=' и'), + 'сто один сум и двадцать два тийина' + ) From d1fe26961cff366c4788e0c4b0f1ae5f4b0d73fb Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Mon, 9 Nov 2020 18:16:22 +0100 Subject: [PATCH 219/340] fix Polish twenties --- num2words/lang_PL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 1fb1fdcd..ec7e6a22 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -80,7 +80,7 @@ 6: ('sześćdziesiąt',), 7: ('siedemdziesiąt',), 8: ('osiemdziesiąt',), - 9: ('dziewięćdzisiąt',), + 9: ('dziewięćdziesiąt',), } TWENTIES_ORDINALS = { From 5878cd07fe1d691ea94149aba014ebbd2eefb4af Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Mon, 9 Nov 2020 18:26:47 +0100 Subject: [PATCH 220/340] adapt polish tests --- tests/test_pl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_pl.py b/tests/test_pl.py index 147a747c..cf6e18ad 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -52,7 +52,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'), @@ -62,20 +62,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( From e4b75bb00d2fa55522995563e00eb08b78887546 Mon Sep 17 00:00:00 2001 From: cyriaka90 Date: Tue, 16 Aug 2022 14:58:50 +0200 Subject: [PATCH 221/340] increase Polish test coverage --- tests/test_pl.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_pl.py b/tests/test_pl.py index cf6e18ad..08ef0394 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -24,11 +24,13 @@ 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") @@ -94,6 +96,9 @@ def test_to_ordinal(self): 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( @@ -118,6 +123,10 @@ def test_to_ordinal(self): self.assertEqual(num2words(1000000, lang='pl', to='ordinal'), "milionowy") + def test_to_ordinal_error(self): + with self.assertRaises(NotImplementedError): + num2words(1.5, lang='pl', to='ordinal') + def test_currency(self): self.assertEqual( num2words(1.0, lang='pl', to='currency', currency='EUR'), From 3dda6ee22e5278fa9621f9fb37dc8de2e5dc230d Mon Sep 17 00:00:00 2001 From: Sergio Zanchetta Date: Sun, 16 Jan 2022 00:52:24 +0100 Subject: [PATCH 222/340] Add to_currency and CURRENCY_FORMS for italian --- num2words/lang_IT.py | 119 +++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index 6966d730..d532f7f4 100644 --- a/num2words/lang_IT.py +++ b/num2words/lang_IT.py @@ -16,6 +16,8 @@ from __future__ import unicode_literals +from .lang_EU import Num2Word_EU + # Globals # ------- @@ -43,57 +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" - .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 +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 @@ -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 From 593435f21a675e317ee42fb3b2717bdd95eb43c4 Mon Sep 17 00:00:00 2001 From: Sergio Zanchetta Date: Sun, 16 Jan 2022 12:07:43 +0100 Subject: [PATCH 223/340] Add tests for italian language currencies --- tests/test_it.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/test_it.py b/tests/test_it.py index 348f4ed8..9023355f 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 @@ -240,3 +270,24 @@ def test_with_decimals(self): self.assertAlmostEqual( num2words(1.1, lang="it"), "uno virgola uno" ) + + 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] + ) From 44a2b7cc2db2de0e71416982fbb2e5477ec44ebf Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 19:11:37 +0300 Subject: [PATCH 224/340] [TEST] ordinal_num test --- tests/test_tr.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_tr.py b/tests/test_tr.py index 84252624..2da70010 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -183,6 +183,10 @@ def test_tr(self): "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ı"} ] for casedata in testcases: From 75eec68f3ed8d7f6ec9e316ec994a98d879ad166 Mon Sep 17 00:00:00 2001 From: Antoine Planchot Date: Fri, 14 May 2021 22:31:46 +0200 Subject: [PATCH 225/340] Added support for Esperanto numbers. --- num2words/__init__.py | 1 + num2words/lang_EO.py | 130 +++++++++++++++++++++++++++++ tests/test_eo.py | 190 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 321 insertions(+) create mode 100644 num2words/lang_EO.py create mode 100644 tests/test_eo.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 3c9171a8..acff85c9 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -38,6 +38,7 @@ '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_NI': lang_ES_NI.Num2Word_ES_NI(), diff --git a/num2words/lang_EO.py b/num2words/lang_EO.py new file mode 100644 index 00000000..473e74d1 --- /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." + ) + 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/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] + ) From 7109e16e73cdc28b8ad48b8e4cb8ed13e8e62195 Mon Sep 17 00:00:00 2001 From: ismail eski Date: Wed, 17 Aug 2022 19:56:11 +0300 Subject: [PATCH 226/340] [TEST] ordinal_num test --- tests/test_tr.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 2da70010..d01ba060 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -182,10 +182,10 @@ def test_tr(self): {"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ü"} + "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ı"} ] From b6a80e0e2a381cc830effc964fcc2119e201bdbc Mon Sep 17 00:00:00 2001 From: ismail eski Date: Thu, 18 Aug 2022 18:48:10 +0300 Subject: [PATCH 227/340] [FIX] E231 missing whitespace after ',' --- tests/test_tr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index d01ba060..e1aefba5 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -184,9 +184,9 @@ def test_tr(self): {"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": 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ı"} ] for casedata in testcases: From 2ee06aa086cc609f48d4869725213da874315dc2 Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Thu, 18 Aug 2022 18:59:35 +0200 Subject: [PATCH 228/340] reformatting --- num2words/__init__.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index acff85c9..fb9f7e91 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,12 +18,13 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, - lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, - lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, - lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, - lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, - lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, - lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) + lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, + lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, + lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, + lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, + lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, + lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, + lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 0865ac247e10ece70fb1d330f69d751624e14cb7 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Date: Fri, 19 Aug 2022 10:28:08 -0400 Subject: [PATCH 229/340] new release --- CHANGES.rst | 19 +++++++++++++++++-- bin/num2words | 4 ++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9f3a7b24..4a1d1e1d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,21 @@ Changelog ========= +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 ---------------------------- @@ -77,9 +92,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/bin/num2words b/bin/num2words index 2a20b225..26990c01 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 @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.11" +__version__ = "0.5.12" __license__ = "LGPL" From 3ffdbec8e0bad4fe740500404aa8446ad4a9e5a8 Mon Sep 17 00:00:00 2001 From: Yunus Emre Geldegul Date: Fri, 19 Aug 2022 23:37:53 +0300 Subject: [PATCH 230/340] #454: [tr] fix negative number problem --- num2words/lang_TR.py | 48 +++++++++++++++++++++++++------------------- tests/test_tr.py | 6 +++++- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index ee1d6d4c..2f20dd66 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -124,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: @@ -137,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( @@ -146,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: @@ -156,7 +162,7 @@ def to_cardinal(self, value): ) if self.integers_to_read[0][0] == "0": return self.ZERO - return wrd + return "%s%s" % (pre_word, wrd) if self.total_digits_outside_triplets == 0: if self.order_of_last_zero_digit == 2: @@ -165,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( @@ -175,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( @@ -188,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: @@ -202,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 @@ -216,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 @@ -244,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 @@ -268,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 @@ -283,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 @@ -299,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 @@ -339,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] @@ -357,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][ @@ -381,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: @@ -398,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: @@ -435,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) diff --git a/tests/test_tr.py b/tests/test_tr.py index e1aefba5..59c88c79 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -186,7 +186,11 @@ def test_tr(self): {"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": 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"}, ] for casedata in testcases: From ddf6a88af61e6c8357884583be5e7ee0073f8323 Mon Sep 17 00:00:00 2001 From: Yunus Emre Geldegul Date: Fri, 19 Aug 2022 23:51:30 +0300 Subject: [PATCH 231/340] #454: [tr] fix flake8 E501 problem --- tests/test_tr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index 59c88c79..da7bacd8 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -189,7 +189,8 @@ def test_tr(self): {"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": -576, "to": "cardinal", + "expected": u"eksibeşyüzyetmişaltı"}, {"test": -3, "to": "currency", "expected": u"eksiüçlira"}, ] From a7d095c97db49c9583af02655676f6c1d82332f5 Mon Sep 17 00:00:00 2001 From: Yunus Emre Geldegul Date: Fri, 19 Aug 2022 23:56:14 +0300 Subject: [PATCH 232/340] #454: [tr] fix flake8 E128 --- tests/test_tr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_tr.py b/tests/test_tr.py index da7bacd8..4a341af1 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -190,7 +190,7 @@ def test_tr(self): {"test": -5, "to": "cardinal", "expected": u"eksibeş"}, {"test": -55, "to": "cardinal", "expected": u"eksiellibeş"}, {"test": -576, "to": "cardinal", - "expected": u"eksibeşyüzyetmişaltı"}, + "expected": u"eksibeşyüzyetmişaltı"}, {"test": -3, "to": "currency", "expected": u"eksiüçlira"}, ] From 9e6cdac35d6ece1f075d7880c006e334bfc4edcd Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 13:17:52 +0100 Subject: [PATCH 233/340] removed hyphen between tens and units --- num2words/lang_NO.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index 0fb43e43..56bc8db8 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -50,8 +50,7 @@ def setup(self): "tolv", "elleve", "ti", "ni", "\xe5tte", "syv", "seks", "fem", "fire", "tre", "to", "en", "null"] - self.ords = {"en": "f\xf8rste", - "to": "andre", + self.ords_pl = {"to": "andre", "tre": "tredje", "fire": "fjerde", "fem": "femte", @@ -62,7 +61,15 @@ def setup(self): "ti": "tiende", "elleve": "ellevte", "tolv": "tolvte", + "fjorten": "fjortende", + "femten": "femtende", + "seksten": "sekstende", + "sytten": "syttende", + "atten": "attende", + "nitten": "nittende", "tjue": "tjuende"} + # this needs to be done separately to not block 13-19 to_ordinal (as they all end with "-en") + self.ords_sg = {"en": "f\xf8rste"} def merge(self, lpair, rpair): ltext, lnum = lpair @@ -70,7 +77,7 @@ 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: @@ -79,19 +86,16 @@ def merge(self, lpair, rpair): 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) From 720e3ca53199be3758a1b7b34015b6bbf99ce8d1 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 13:18:16 +0100 Subject: [PATCH 234/340] corrected ordinal_num --- num2words/lang_NO.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index 56bc8db8..eca8499c 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -99,7 +99,7 @@ def to_ordinal(self, value): 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: From f123eba1c463012687bc4ae3b67eaf0673b196e3 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 13:32:09 +0100 Subject: [PATCH 235/340] fixed NO currency --- num2words/lang_NO.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index eca8499c..f82d4a59 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) @@ -107,6 +108,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 From 5b388796600b5b62d9a2571ae9f04ca3b1070bc0 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 13:33:04 +0100 Subject: [PATCH 236/340] removed comma from word form of large numbers --- num2words/lang_NO.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index f82d4a59..f14360fd 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -83,7 +83,7 @@ def merge(self, lpair, rpair): 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) From 2d5b795e0231abee8f7ccd2e53c387bfc0c19975 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 13:33:13 +0100 Subject: [PATCH 237/340] added Norwegian test cases --- tests/test_no.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tests/test_no.py diff --git a/tests/test_no.py b/tests/test_no.py new file mode 100644 index 00000000..06f40886 --- /dev/null +++ b/tests/test_no.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 __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(1435, to="ordinal", lang="no"), + "en tusen fire hundre og trettifemte") + + 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") + From 4596667c08969912cbf3dc758edb5e390ccd1938 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 5 Oct 2022 17:21:38 +0100 Subject: [PATCH 238/340] formatting --- num2words/lang_NO.py | 40 ++++++++++++++++++++-------------------- tests/test_no.py | 32 +++++++++++++++++++------------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index f14360fd..8c0c56f8 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -52,24 +52,24 @@ def setup(self): "syv", "seks", "fem", "fire", "tre", "to", "en", "null"] 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"} - # this needs to be done separately to not block 13-19 to_ordinal (as they all end with "-en") + "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"} + # this needs to be done separately to not block 13-19 to_ordinal self.ords_sg = {"en": "f\xf8rste"} def merge(self, lpair, rpair): @@ -113,7 +113,7 @@ def to_currency(self, val, currency='NOK', cents=True, separator=' og', result = super(Num2Word_NO, self).to_currency( val, currency=currency, cents=cents, separator=separator, adjective=adjective) - - # do not print "og null øre" + + # do not print "og null øre" result = result.replace(' og null øre', '') return result diff --git a/tests/test_no.py b/tests/test_no.py index 06f40886..16fad888 100644 --- a/tests/test_no.py +++ b/tests/test_no.py @@ -41,18 +41,19 @@ def test_cardinal(self): "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") - + 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(30, to="ordinal", lang="no"), "trettiende") + self.assertEqual(num2words(32, to="ordinal", lang="no"), "trettiandre") self.assertEqual(num2words(1435, to="ordinal", lang="no"), "en tusen fire hundre og trettifemte") - + 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.") @@ -61,13 +62,18 @@ def test_ordinal_num(self): 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") - + 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") - + 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") From b6ebdac6e4b55deea11a4e3fe735adca1f5b64d7 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 12 Oct 2022 18:05:19 +0100 Subject: [PATCH 239/340] further ordinal coverage --- num2words/lang_NO.py | 5 ++++- tests/test_no.py | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index 8c0c56f8..b4d33380 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -68,7 +68,10 @@ def setup(self): "sytten": "syttende", "atten": "attende", "nitten": "nittende", - "tjue": "tjuende"} + "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"} diff --git a/tests/test_no.py b/tests/test_no.py index 16fad888..92ed8603 100644 --- a/tests/test_no.py +++ b/tests/test_no.py @@ -51,8 +51,12 @@ def test_ordinal(self): 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.") From f58d9540a7622b0fb0e7939761fe4d040aa645fb Mon Sep 17 00:00:00 2001 From: George Date: Thu, 13 Oct 2022 10:01:57 +0100 Subject: [PATCH 240/340] new test linting --- tests/test_no.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_no.py b/tests/test_no.py index 92ed8603..1b29061b 100644 --- a/tests/test_no.py +++ b/tests/test_no.py @@ -51,8 +51,10 @@ def test_ordinal(self): 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(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"), From 6a26a0b9686cdfc8cba683238277919cb79bf8a0 Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Tue, 8 Nov 2022 14:11:15 +0100 Subject: [PATCH 241/340] [FIX]flake8 for 3.10 line length fix --- num2words/lang_PL.py | 11 ++++++++++- num2words/lang_RU.py | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index a692f23f..92ff9678 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -156,7 +156,16 @@ class Num2Word_PL(Num2Word_Base): ('euro', 'euro', 'euro'), ('cent', 'centy', 'centów') ), 'USD': ( - ('dolar amerykański', 'dolary amerykańskie', 'dolarów amerykańskich'), ('cent', 'centy', 'centów') + ( + 'dolar amerykański', + 'dolary amerykańskie', + 'dolarów amerykańskich' + ), + ( + 'cent', + 'centy', + 'centów' + ) ), } diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 77fe441f..b521cfed 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -114,7 +114,8 @@ class Num2Word_RU(Num2Word_Base): ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') ), 'BYN': ( - ('белорусский рубль', 'белорусских рубля', 'белорусских рублей'), ('копейка', 'копейки', 'копеек') + ('белорусский рубль', 'белорусских рубля', 'белорусских рублей'), + ('копейка', 'копейки', 'копеек') ), 'UZS': ( ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') From 8e5b2dcdec713435010e940de49d212d839f40d4 Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Tue, 15 Nov 2022 11:43:29 +0100 Subject: [PATCH 242/340] [ADD]PLN in ru to be reverted(?) --- bin/num2words | 2 +- num2words/lang_RU.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/num2words b/bin/num2words index 26990c01..0d1580a0 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.12" +__version__ = "0.5.13" __license__ = "LGPL" diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index b521cfed..23578921 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -120,6 +120,9 @@ class Num2Word_RU(Num2Word_Base): 'UZS': ( ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') ), + 'PLN': ( + ('польский злотый', 'польских слотых', 'польских злотых'), ('грош', 'гроша', 'грошей') + ), } def setup(self): From 4d300317e990b4ca9859a27646e8cc1b9732686e Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 25 Nov 2022 14:57:59 +0100 Subject: [PATCH 243/340] changed ktiv haser to ktiv male (long form when not using diacritics) --- num2words/lang_HE.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index f9871925..9e08ebad 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -25,8 +25,8 @@ ONES = { 1: (u'אחת',), - 2: (u'שתים',), - 3: (u'שלש',), + 2: (u'שתיים',), + 3: (u'שלוש',), 4: (u'ארבע',), 5: (u'חמש',), 6: (u'שש',), @@ -39,7 +39,7 @@ 0: (u'עשר',), 1: (u'אחת עשרה',), 2: (u'שתים עשרה',), - 3: (u'שלש עשרה',), + 3: (u'שלוש עשרה',), 4: (u'ארבע עשרה',), 5: (u'חמש עשרה',), 6: (u'שש עשרה',), @@ -50,10 +50,10 @@ TWENTIES = { 2: (u'עשרים',), - 3: (u'שלשים',), + 3: (u'שלושים',), 4: (u'ארבעים',), 5: (u'חמישים',), - 6: (u'ששים',), + 6: (u'שישים',), 7: (u'שבעים',), 8: (u'שמונים',), 9: (u'תשעים',), @@ -68,7 +68,7 @@ THOUSANDS = { 1: (u'אלף',), 2: (u'אלפיים',), - 3: (u'שלשת אלפים',), + 3: (u'שלושת אלפים',), 4: (u'ארבעת אלפים',), 5: (u'חמשת אלפים',), 6: (u'ששת אלפים',), From 36a025b498046720daf81caf171322af03b2cc4c Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 13:43:16 +0000 Subject: [PATCH 244/340] change hebrew spelling from biblical and short-form (ktiv haser) to modern long-form (ktiv male); add hebrew gender; and hebrew ordinals; add hebrew decimal fraction and negative; fix hebrew word order for singular; fix hebrew currency names; fix global double space after minus; fix tests --- bin/num2words | 6 +- num2words/base.py | 6 +- num2words/lang_HE.py | 173 +++++++++++++++++++++++++++++++------------ tests/test_cli.py | 8 +- tests/test_en.py | 6 ++ tests/test_he.py | 77 ++++++++++++------- 6 files changed, 193 insertions(+), 83 deletions(-) diff --git a/bin/num2words b/bin/num2words index 26990c01..06ff0443 100755 --- a/bin/num2words +++ b/bin/num2words @@ -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/base.py b/num2words/base.py index 0929cb93..243045ff 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -94,7 +94,7 @@ 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): @@ -109,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)) @@ -292,7 +292,7 @@ def to_currency(self, val, currency='EUR', cents=True, separator=',', 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) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 9e08ebad..fb49c7f1 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -19,33 +19,36 @@ from __future__ import print_function, unicode_literals from .base import Num2Word_Base +from .compat import to_s +from .currency import parse_currency_parts, prefix_currency 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'ראשון'), + 2: (u'שתיים', u'שניים', u'שנייה', u'שני'), + 3: (u'שלוש', u'שלושה', u'שלישית', u'שלישי'), + 4: (u'ארבע', u'ארבעה', u'רביעית', u'רביעי'), + 5: (u'חמש', u'חמישה', u'חמישית', u'חמישי'), + 6: (u'שש', u'שישה', u'שישית', u'שישי'), + 7: (u'שבע', u'שבעה', u'שביעית', u'שביעי'), + 8: (u'שמונה', u'שמונה', u'שמינית', u'שמיני'), + 9: (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'עשירי'), + 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'תשעה עשר'), } TWENTIES = { @@ -79,14 +82,11 @@ AND = u'ו' +MAXVAL = 10000 -def pluralize(n, forms): - form = 1 if n == 0 else 0 if n == 1 else 1 - return forms[form] - - -def int2word(n): - if n > 9999: # doesn't yet work for numbers this big +def int2word(n, gender='f', ordinal=False): + assert n == int(n) + if n >= MAXVAL: # doesn't yet work for numbers this big raise NotImplementedError() if n == 0: @@ -118,47 +118,126 @@ def int2word(n): words.append(TWENTIES[n2][0]) if n2 == 1: - words.append(TENS[n1][0]) + words.append(TENS[n1][(gender == 'm') + ordinal*(not n1)]) elif n1 > 0 and not (i > 0 and x == 1): - words.append(ONES[n1][0]) + words.append(ONES[n1][(gender == 'm') + ordinal*(x < 11)]) if i > 0: words.append(THOUSANDS[i][0]) - # source: https://hebrew-academy.org.il/2017/01/30/ו-החיבור-במספרים/ + # source: 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 if len(words) > 1: words[-1] = AND + words[-1] return ' '.join(words) -def n2w(n): - return int2word(int(n)) - - class Num2Word_HE(Num2Word_Base): CURRENCY_FORMS = { - 'NIS': (('שקל', 'שקלים'), ('אגורה', 'אגורות')), - 'EUR': (('אירו', 'אירו'), ('סנט', 'סנט')), - 'USD': (('דולר', 'דולרים'), ('סנט', 'סנט')), + 'ILS': ((u'שקל', u'שקלים'), (u'אגורה', u'אגורות')), + 'EUR': ((u'אירו', u'אירו'), (u'סנט', u'סנטים')), + 'USD': ((u'דולר', u'דולרים'), (u'סנט', u'סנטים')), } - def to_cardinal(self, number): - return n2w(number) + CURRENCY_GENDERS = { + 'ILS': ('m', 'f'), + 'EUR': ('m', 'm'), + 'USD': ('m', 'm'), + } - def to_ordinal(self, number): - raise NotImplementedError() + 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'): + try: + assert int(value) == value + except (ValueError, TypeError, AssertionError): + return self.to_cardinal_float(value, gender) # 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/ + + 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, ordinal=False) + + def to_ordinal(self, value, gender='m'): + self.verify_ordinal(value) + out = int2word(int(value), gender, ordinal=True) + if value == 0 or value > 10: + out = 'ה' + out + return out def pluralize(self, n, forms): - return pluralize(n, forms) + assert n == int(n) + form = 0 if n == 1 else 1 + return forms[form] + - def to_currency(self, val, currency='NIS', cents=True, separator=' ו', + def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, adjective=False): - result = super(Num2Word_HE, self).to_currency( - val, currency=currency, cents=cents, separator=separator, - adjective=adjective) - # In Hebrew the separator is along with the following word - return result.replace(" ו ", " ו") + 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 "" + try: + gender1, gender2 = self.CURRENCY_GENDERS[currency] + except KeyError: + gender1 = gender2 = '' + + money_str = self.to_cardinal(left, gender=gender1) + cents_str = self.to_cardinal(right, gender=gender2) \ + if cents else self._cents_terse(right, currency) + + strings = [ + minus_str, + money_str, + self.pluralize(left, cr1), + separator, + cents_str, + self.pluralize(right, cr2) + ] + if left == 1: + strings[1], strings[2] = strings[2], strings[1] + if right == 1: + strings[4], strings[5] = strings[5], strings[4] + return u'%s%s %s%s%s %s' % tuple(strings) # In Hebrew the separator is along with the following word if __name__ == '__main__': diff --git a/tests/test_cli.py b/tests/test_cli.py index a85b1250..79610cb7 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -59,12 +59,12 @@ def test_cli_list_langs(self): 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): @@ -73,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): diff --git a/tests/test_en.py b/tests/test_en.py index e763841c..de934717 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -95,6 +95,12 @@ def test_to_currency(self): "one dollar and one cent" ) + self.assertEqual( + 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', separator=' and', cents=True, currency='USD', adjective=True), diff --git a/tests/test_he.py b/tests/test_he.py index e50a6a22..82a2aeeb 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -31,25 +31,25 @@ def test_0(self): def test_1_to_10(self): self.assertEqual(num2words(1, lang="he"), u'אחת') - self.assertEqual(num2words(2, lang="he"), u'שתים') + self.assertEqual(num2words(2, lang="he"), u'שתיים') self.assertEqual(num2words(7, lang="he"), u'שבע') self.assertEqual(num2words(10, lang="he"), u'עשר') def test_11_to_19(self): self.assertEqual(num2words(11, lang="he"), u'אחת עשרה') - self.assertEqual(num2words(13, lang="he"), u'שלש עשרה') + self.assertEqual(num2words(13, lang="he"), u'שלוש עשרה') self.assertEqual(num2words(15, lang="he"), u'חמש עשרה') self.assertEqual(num2words(16, lang="he"), 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"), u'עשרים ושלוש') self.assertEqual(num2words(28, lang="he"), u'עשרים ושמונה') - self.assertEqual(num2words(31, 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'תשעים ושתים') + 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'מאה') @@ -65,7 +65,7 @@ def test_1000_to_9999(self): self.assertEqual(num2words(1001, lang="he"), u'אלף ואחת') self.assertEqual(num2words(1500, lang="he"), u'אלף וחמש מאות') self.assertEqual( - num2words(7378, lang="he"), u'שבעת אלפים שלש מאות שבעים ושמונה' + num2words(7378, lang="he"), u'שבעת אלפים שלוש מאות שבעים ושמונה' ) self.assertEqual(num2words(2000, lang="he"), u'אלפיים') self.assertEqual(num2words(2100, lang="he"), u'אלפיים ומאה') @@ -75,42 +75,67 @@ def test_1000_to_9999(self): def test_pluralize(self): n = Num2Word_HE() - cr1, cr2 = n.CURRENCY_FORMS['NIS'] - self.assertEqual(n.pluralize(1, cr1), 'שקל') - self.assertEqual(n.pluralize(2, cr1), 'שקלים') - self.assertEqual(n.pluralize(1, cr2), 'אגורה') - self.assertEqual(n.pluralize(2, cr2), 'אגורות') + 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), 'דולר') - self.assertEqual(n.pluralize(2, cr1), 'דולרים') - self.assertEqual(n.pluralize(1, cr2), 'סנט') - self.assertEqual(n.pluralize(2, cr2), 'סנט') + 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='NIS'), 'עשרים שקלים ואפס אגורות' + n.to_currency(20.0, currency='ILS'), u'עשרים שקלים ואפס אגורות' ) self.assertEqual( - n.to_currency(100.0, currency='NIS'), 'מאה שקלים ואפס אגורות' + n.to_currency(100.0, currency='ILS'), u'מאה שקלים ואפס אגורות' ) self.assertEqual( - n.to_currency(100.50, currency='NIS'), 'מאה שקלים וחמישים אגורות' + 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(1.01, currency='ILS'), u'שקל אחד ואגורה אחת' + ) + self.assertEqual( + n.to_currency(-1.01, currency='ILS'), u'מינוס שקל אחד ואגורה אחת' ) def test_to_cardinal(self): n = Num2Word_HE() self.assertEqual(n.to_cardinal(1500), u'אלף וחמש מאות') - - -class Num2WordsHETestNotImplementedMethofs(TestCase): - n = Num2Word_HE() + self.assertEqual(n.to_cardinal(1501), u'אלף חמש מאות ואחת') def test_to_ordinal(self): - with self.assertRaises(NotImplementedError): - self.n.to_ordinal('1') + n = Num2Word_HE() + self.assertEqual(n.to_ordinal(1500), u'האלף וחמש מאות') + self.assertEqual(n.to_ordinal(1501), 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'שנים עשר נקודה חמש תשע ארבע אחת שלוש שתיים') + + +class Num2WordsHETestNotImplementedMethods(TestCase): + n = Num2Word_HE() def test_large_number(self): - with self.assertRaises(NotImplementedError): + with self.assertRaises(OverflowError): num2words(2000000, lang="he") From e617d26fac6dc3a259669238787c1cfc9f91e5c4 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 13:56:31 +0000 Subject: [PATCH 245/340] remove duplicate test --- tests/test_en.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/test_en.py b/tests/test_en.py index de934717..e763841c 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -95,12 +95,6 @@ def test_to_currency(self): "one dollar and one cent" ) - self.assertEqual( - 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', separator=' and', cents=True, currency='USD', adjective=True), From 16f2641fcef666c460c72b9753463fb546ccc566 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 14:31:40 +0000 Subject: [PATCH 246/340] add definite ordinals; fix ordinal bugs; add more ordinal tests --- num2words/lang_HE.py | 31 +++++++++++++++++++------------ tests/test_he.py | 12 ++++++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index fb49c7f1..30841e3f 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -82,14 +82,19 @@ AND = u'ו' +DEF = u'ה' + MAXVAL = 10000 -def int2word(n, gender='f', ordinal=False): + +def int2word(n, gender='f', ordinal=False, definite=False): assert n == int(n) if n >= MAXVAL: # doesn't yet work for numbers this big raise NotImplementedError() if n == 0: + if ordinal: + return DEF + ZERO[0] return ZERO[0] words = [] @@ -118,9 +123,9 @@ def int2word(n, gender='f', ordinal=False): words.append(TWENTIES[n2][0]) if n2 == 1: - words.append(TENS[n1][(gender == 'm') + ordinal*(not n1)]) + words.append(TENS[n1][(gender == 'm') + 2*ordinal*(not n1)]) elif n1 > 0 and not (i > 0 and x == 1): - words.append(ONES[n1][(gender == 'm') + ordinal*(x < 11)]) + words.append(ONES[n1][(gender == 'm') + 2*ordinal*(x < 11)]) if i > 0: words.append(THOUSANDS[i][0]) @@ -129,6 +134,9 @@ def int2word(n, gender='f', ordinal=False): if len(words) > 1: words[-1] = AND + words[-1] + if ordinal and (n > 10 or definite): + words[0] = DEF + words[0] + return ' '.join(words) @@ -173,12 +181,11 @@ def to_cardinal_float(self, value, gender='f'): return " ".join(out) - def to_cardinal(self, value, gender='f'): try: assert int(value) == value except (ValueError, TypeError, AssertionError): - return self.to_cardinal_float(value, gender) # 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/ + return self.to_cardinal_float(value, gender=gender) # 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/ out = "" if value < 0: @@ -188,21 +195,21 @@ def to_cardinal(self, value, gender='f'): if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) - return out + int2word(int(value), gender, ordinal=False) + return out + int2word(int(value), gender=gender, ordinal=False) - def to_ordinal(self, value, gender='m'): + def to_ordinal(self, value, gender='m', definite=False): self.verify_ordinal(value) - out = int2word(int(value), gender, ordinal=True) - if value == 0 or value > 10: - out = 'ה' + out - return out + + if value >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) + + return int2word(int(value), gender=gender, ordinal=True, definite=definite) def pluralize(self, n, forms): assert n == int(n) form = 0 if n == 1 else 1 return forms[form] - def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, adjective=False): left, right, is_negative = parse_currency_parts(val) diff --git a/tests/test_he.py b/tests/test_he.py index 82a2aeeb..b5afc6ee 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -120,6 +120,15 @@ def test_to_ordinal(self): n = Num2Word_HE() 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(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'האפס') def test_cardinal_for_float_number(self): self.assertEqual(num2words(12.5, lang='he'), u'שתים עשרה נקודה חמש') @@ -139,3 +148,6 @@ class Num2WordsHETestNotImplementedMethods(TestCase): def test_large_number(self): with self.assertRaises(OverflowError): num2words(2000000, lang="he") + + with self.assertRaises(OverflowError): + num2words(2000000, lang="he", ordinal=True) From f8776dd3690268576c2c9c8fa1962714d659d0c5 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 15:36:39 +0000 Subject: [PATCH 247/340] allow to prefer singular forms --- num2words/lang_HE.py | 12 +++++++----- tests/test_he.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 30841e3f..2af2dda3 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -205,13 +205,15 @@ def to_ordinal(self, value, gender='m', definite=False): return int2word(int(value), gender=gender, ordinal=True, definite=definite) - def pluralize(self, n, forms): + def pluralize(self, n, forms, currency=None, is_negative=False, prefer_singular=False): assert n == int(n) - form = 0 if n == 1 else 1 + form = 1 + if n == 1 or prefer_singular and (n > 10 or n == 0 or is_negative or currency != 'ILS'): + form = 0 return forms[form] def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, - adjective=False): + adjective=False, prefer_singular=False, prefer_singular_cents=False): left, right, is_negative = parse_currency_parts(val) try: @@ -235,10 +237,10 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, strings = [ minus_str, money_str, - self.pluralize(left, cr1), + self.pluralize(left, cr1, currency=currency, is_negative=is_negative, prefer_singular=prefer_singular), separator, cents_str, - self.pluralize(right, cr2) + self.pluralize(right, cr2, currency=currency, is_negative=is_negative, prefer_singular=prefer_singular_cents) ] if left == 1: strings[1], strings[2] = strings[2], strings[1] diff --git a/tests/test_he.py b/tests/test_he.py index b5afc6ee..5ac39903 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -104,12 +104,36 @@ def test_to_currency(self): 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(1.01, currency='ILS'), u'שקל אחד ואגורה אחת' ) self.assertEqual( n.to_currency(-1.01, 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'חמישה דולר וחמישה סנט' + ) def test_to_cardinal(self): n = Num2Word_HE() From 8f27e6ad02d90fe61086c4328b846762a97b4cde Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 16:39:40 +0000 Subject: [PATCH 248/340] support kwargs for old ordinal interface --- num2words/__init__.py | 2 +- tests/test_he.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index fb9f7e91..e30fd01e 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -90,7 +90,7 @@ def num2words(number, ordinal=False, lang='en', to='cardinal', **kwargs): # backwards compatible if ordinal: - return converter.to_ordinal(number) + to = 'ordinal' if to not in CONVERTES_TYPES: raise NotImplementedError() diff --git a/tests/test_he.py b/tests/test_he.py index 5ac39903..aef17063 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -139,6 +139,8 @@ 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() @@ -153,6 +155,10 @@ def test_to_ordinal(self): 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(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_cardinal_for_float_number(self): self.assertEqual(num2words(12.5, lang='he'), u'שתים עשרה נקודה חמש') From 04c0765b995f9c249eab8def61285b1c4722263f Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 2 Dec 2022 17:47:14 +0000 Subject: [PATCH 249/340] raised maxval to 1,000,000 --- num2words/lang_HE.py | 29 ++++++++++++++++------------- tests/test_he.py | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 2af2dda3..addf3c5c 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -78,13 +78,14 @@ 7: (u'שבעת אלפים',), 8: (u'שמונת אלפים',), 9: (u'תשעת אלפים',), + 10: (u'עשרת אלפים',), } AND = u'ו' DEF = u'ה' -MAXVAL = 10000 +MAXVAL = 1000000 def int2word(n, gender='f', ordinal=False, definite=False): @@ -109,10 +110,6 @@ def int2word(n, gender='f', ordinal=False, definite=False): n1, n2, n3 = get_digits(x) - if i > 0: - words.append(THOUSANDS[n1][0]) - continue - if n3 > 0: if n3 <= 2: words.append(HUNDRED[n3][0]) @@ -122,17 +119,23 @@ def int2word(n, gender='f', ordinal=False, definite=False): if n2 > 1: words.append(TWENTIES[n2][0]) - if n2 == 1: - words.append(TENS[n1][(gender == 'm') + 2*ordinal*(not n1)]) - elif n1 > 0 and not (i > 0 and x == 1): - words.append(ONES[n1][(gender == 'm') + 2*ordinal*(x < 11)]) + if i == 0 or x > 10: + if n2 == 1: + words.append( + TENS[n1][(gender == 'm' or i > 0) + 2 * ordinal * (not n1)]) + elif n1 > 0: + words.append( + ONES[n1][(gender == 'm' or i > 0) + 2 * ordinal * (x < 11)]) if i > 0: - words.append(THOUSANDS[i][0]) + if x < 11: + words.append(THOUSANDS[x][0]) + else: + words[-1] = words[-1] + ' ' + THOUSANDS[1][0] - # source: 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 - if len(words) > 1: - words[-1] = AND + words[-1] + # source: 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 + if len(words) > 1: + words[-1] = AND + words[-1] if ordinal and (n > 10 or definite): words[0] = DEF + words[0] diff --git a/tests/test_he.py b/tests/test_he.py index aef17063..27785822 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -64,14 +64,41 @@ def test_1000_to_9999(self): self.assertEqual(num2words(1000, lang="he"), u'אלף') self.assertEqual(num2words(1001, lang="he"), u'אלף ואחת') self.assertEqual(num2words(1500, lang="he"), u'אלף וחמש מאות') - self.assertEqual( - num2words(7378, lang="he"), u'שבעת אלפים שלוש מאות שבעים ושמונה' - ) self.assertEqual(num2words(2000, lang="he"), u'אלפיים') self.assertEqual(num2words(2100, lang="he"), 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(10001, lang="he"), 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(20000, lang="he"), u'עשרים אלף') + self.assertEqual(num2words(21000, lang="he"), 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(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(737812, lang="he"), u'שבע מאות שלושים ושבעה אלף שמונה מאות ושתים עשרה') + self.assertEqual(num2words(999999, lang="he"), u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') def test_pluralize(self): n = Num2Word_HE() @@ -155,6 +182,8 @@ def test_to_ordinal(self): 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'הראשון') From b487f3e22cd56d1f729b5d9ce34d9a88fd51db91 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 14:56:59 +0000 Subject: [PATCH 250/340] raised maxval to 1e15; added construct forms --- num2words/lang_HE.py | 102 ++++++++++++++++++++++++------------------- tests/test_he.py | 87 +++++++++++++++++++++++++++++++++++- 2 files changed, 142 insertions(+), 47 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index addf3c5c..535f9ecc 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -27,28 +27,22 @@ ZERO = (u'אפס',) ONES = { - 1: (u'אחת', u'אחד', u'ראשונה', u'ראשון'), - 2: (u'שתיים', u'שניים', u'שנייה', u'שני'), - 3: (u'שלוש', u'שלושה', u'שלישית', u'שלישי'), - 4: (u'ארבע', u'ארבעה', u'רביעית', u'רביעי'), - 5: (u'חמש', u'חמישה', u'חמישית', u'חמישי'), - 6: (u'שש', u'שישה', u'שישית', u'שישי'), - 7: (u'שבע', u'שבעה', u'שביעית', u'שביעי'), - 8: (u'שמונה', u'שמונה', u'שמינית', u'שמיני'), - 9: (u'תשע', u'תשעה', u'תשיעית', u'תשיעי'), + 1: (u'אחת', u'אחד', u'אחת', u'אחד', u'ראשונה', u'ראשון'), + 2: (u'שתיים', u'שניים', u'שתי', u'שני', u'שנייה', u'שני'), + 3: (u'שלוש', u'שלושה', u'שלוש', u'שלושת', u'שלישית', u'שלישי'), + 4: (u'ארבע', u'ארבעה', u'ארבע', u'ארבעת', u'רביעית', u'רביעי'), + 5: (u'חמש', u'חמישה', u'חמש', u'חמשת', u'חמישית', u'חמישי'), + 6: (u'שש', u'שישה', u'שש', u'ששת', u'שישית', u'שישי'), + 7: (u'שבע', u'שבעה', u'שבע', u'שבעת', u'שביעית', u'שביעי'), + 8: (u'שמונה', u'שמונה', u'שמונה', u'שמונת', u'שמינית', u'שמיני'), + 9: (u'תשע', u'תשעה', u'תשע', u'תשעת', u'תשיעית', u'תשיעי'), } TENS = { - 0: (u'עשר', u'עשרה', u'עשירית', u'עשירי'), + 0: (u'עשר', u'עשרה', u'עשר', u'עשרת', u'עשירית', u'עשירי'), 1: (u'אחת עשרה', u'אחד עשר'), 2: (u'שתים עשרה', u'שנים עשר'), - 3: (u'שלוש עשרה', u'שלושה עשר'), - 4: (u'ארבע עשרה', u'ארבעה עשר'), - 5: (u'חמש עשרה', u'חמישה עשר'), - 6: (u'שש עשרה', u'שישה עשר'), - 7: (u'שבע עשרה', u'שבעה עשר'), - 8: (u'שמונה עשרה', u'שמונה עשר'), - 9: (u'תשע עשרה', u'תשעה עשר'), + 3: (u'עשרה', u'עשר'), } TWENTIES = { @@ -63,7 +57,7 @@ } HUNDRED = { - 1: (u'מאה',), + 1: (u'מאה', u'מאת'), 2: (u'מאתיים',), 3: (u'מאות',) } @@ -71,27 +65,26 @@ THOUSANDS = { 1: (u'אלף',), 2: (u'אלפיים',), - 3: (u'שלושת אלפים',), - 4: (u'ארבעת אלפים',), - 5: (u'חמשת אלפים',), - 6: (u'ששת אלפים',), - 7: (u'שבעת אלפים',), - 8: (u'שמונת אלפים',), - 9: (u'תשעת אלפים',), - 10: (u'עשרת אלפים',), + 3: (u'אלפים', 'אלפי'), +} + +LARGE = { + 1: (u'מיליון', u'מיליוני'), + 2: (u'מיליארד', u'מיליארדי'), + 3: (u'טריליון', u'טריליוני') } AND = u'ו' DEF = u'ה' -MAXVAL = 1000000 +MAXVAL = int(1e15) -def int2word(n, gender='f', ordinal=False, definite=False): +def int2word(n, gender='f', construct=False, ordinal=False, definite=False): assert n == int(n) - if n >= MAXVAL: # doesn't yet work for numbers this big - raise NotImplementedError() + if n >= MAXVAL: + raise OverflowError('abs(%s) must be less than %s.' % (n, MAXVAL)) if n == 0: if ordinal: @@ -111,7 +104,9 @@ def int2word(n, gender='f', ordinal=False, definite=False): n1, n2, n3 = get_digits(x) if n3 > 0: - if n3 <= 2: + if construct and i == 0 and x == 100: + words.append(HUNDRED[n3][1]) + elif n3 <= 2: words.append(HUNDRED[n3][0]) else: words.append(ONES[n3][0] + ' ' + HUNDRED[3][0]) @@ -121,17 +116,34 @@ def int2word(n, gender='f', ordinal=False, definite=False): if i == 0 or x > 10: if n2 == 1: - words.append( - TENS[n1][(gender == 'm' or i > 0) + 2 * ordinal * (not n1)]) + if n1 <= 2: + words.append( + TENS[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and n1 == 0) + 4*ordinal*(n1 == 0)]) + else: + words.append( + ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[3][(gender == 'f' and i > 0)]) elif n1 > 0: words.append( - ONES[n1][(gender == 'm' or i > 0) + 2 * ordinal * (x < 11)]) + ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) - if i > 0: - if x < 11: - words.append(THOUSANDS[x][0]) - else: + if i == 1: + if x >= 11: words[-1] = words[-1] + ' ' + THOUSANDS[1][0] + elif n1 == 0: + words.append(TENS[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) + elif n1 <= 2: + words.append(THOUSANDS[n1][0]) + else: + words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) + elif i > 1: + if x >= 11: + words[-1] = words[-1] + ' ' + LARGE[i-1][construct and n % 1000**i == 0] + elif n1 == 0: + words.append(TENS[n1][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) + elif n1 == 1: + words.append(LARGE[i-1][0]) + else: + words.append(ONES[n1][1 + 2*(construct and n % 1000**i == 0 or x == 2)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) # source: 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 if len(words) > 1: @@ -159,8 +171,8 @@ class Num2Word_HE(Num2Word_Base): def setup(self): super(Num2Word_HE, self).setup() - self.negword = u"מינוס" - self.pointword = u"נקודה" + self.negword = u'מינוס' + self.pointword = u'נקודה' self.MAXVAL = MAXVAL def to_cardinal_float(self, value, gender='f'): @@ -182,9 +194,9 @@ def to_cardinal_float(self, value, gender='f'): curr = int(post[i]) out.append(to_s(self.to_cardinal(curr))) - return " ".join(out) + return ' '.join(out) - def to_cardinal(self, value, gender='f'): + def to_cardinal(self, value, gender='f', construct=False): try: assert int(value) == value except (ValueError, TypeError, AssertionError): @@ -198,7 +210,7 @@ def to_cardinal(self, value, gender='f'): if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) - return out + int2word(int(value), gender=gender, ordinal=False) + return out + int2word(int(value), gender=gender, construct=construct, ordinal=False) def to_ordinal(self, value, gender='m', definite=False): self.verify_ordinal(value) @@ -233,8 +245,8 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, except KeyError: gender1 = gender2 = '' - money_str = self.to_cardinal(left, gender=gender1) - cents_str = self.to_cardinal(right, gender=gender2) \ + money_str = self.to_cardinal(left, gender=gender1, construct=left == 2) + cents_str = self.to_cardinal(right, gender=gender2, construct=right == 2) \ if cents else self._cents_terse(right, currency) strings = [ diff --git a/tests/test_he.py b/tests/test_he.py index 27785822..9aabcec0 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -37,7 +37,9 @@ def test_1_to_10(self): 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(19, lang="he"), u'תשע עשרה') @@ -53,19 +55,31 @@ def test_20_to_99(self): 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(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(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(2100, lang="he"), u'אלפיים ומאה') + self.assertEqual(num2words(2100, 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(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים' ) @@ -78,11 +92,14 @@ def test_1000_to_9999(self): 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(20000, lang="he"), u'עשרים אלף') + self.assertEqual(num2words(20000, lang="he", construct=True), u'עשרים אלף') self.assertEqual(num2words(21000, lang="he"), u'עשרים ואחד אלף') self.assertEqual(num2words(68700, lang="he"), u'שישים ושמונה אלף ושבע מאות') self.assertEqual(num2words(73781, lang="he"), u'שבעים ושלושה אלף שבע מאות שמונים ואחת') @@ -90,6 +107,7 @@ def test_10000_to_99999(self): 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'מאה ועשרה אלף') @@ -97,9 +115,65 @@ def test_100000_to_999999(self): 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'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words(999999999999999, lang="he", gender='m'), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + self.assertEqual(num2words(999999999999999, lang="he", construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words(999999999999999, lang="he", gender='m', construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעת') + def test_pluralize(self): n = Num2Word_HE() cr1, cr2 = n.CURRENCY_FORMS['ILS'] @@ -149,6 +223,15 @@ def test_to_currency(self): 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'חמישה דולרים וחמישה סנטים' ) @@ -206,7 +289,7 @@ class Num2WordsHETestNotImplementedMethods(TestCase): def test_large_number(self): with self.assertRaises(OverflowError): - num2words(2000000, lang="he") + num2words(2e15, lang="he") with self.assertRaises(OverflowError): - num2words(2000000, lang="he", ordinal=True) + num2words(2e15, lang="he", ordinal=True) From 16468d3e96ffc510ab33bfccaaa6ca75febe9dfc Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 15:04:11 +0000 Subject: [PATCH 251/340] do not allow singular form for plural negatives --- num2words/lang_HE.py | 6 +++--- tests/test_he.py | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 535f9ecc..4fd92bb6 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -223,7 +223,7 @@ def to_ordinal(self, value, gender='m', definite=False): def pluralize(self, n, forms, currency=None, is_negative=False, prefer_singular=False): assert n == int(n) form = 1 - if n == 1 or prefer_singular and (n > 10 or n == 0 or is_negative or currency != 'ILS'): + if n == 1 or prefer_singular and (abs(n) > 10 or n == 0 or currency != 'ILS'): form = 0 return forms[form] @@ -252,10 +252,10 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, strings = [ minus_str, money_str, - self.pluralize(left, cr1, currency=currency, is_negative=is_negative, prefer_singular=prefer_singular), + self.pluralize(left, cr1, currency=currency, prefer_singular=prefer_singular), separator, cents_str, - self.pluralize(right, cr2, currency=currency, is_negative=is_negative, prefer_singular=prefer_singular_cents) + self.pluralize(right, cr2, currency=currency, prefer_singular=prefer_singular_cents) ] if left == 1: strings[1], strings[2] = strings[2], strings[1] diff --git a/tests/test_he.py b/tests/test_he.py index 9aabcec0..5b186390 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -217,6 +217,9 @@ def test_to_currency(self): 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(1.01, currency='ILS'), u'שקל אחד ואגורה אחת' ) From 52d7b0236def3f965e064f2eabf0c8f0401c5a99 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 15:06:29 +0000 Subject: [PATCH 252/340] do not allow singular form for plural negatives --- num2words/lang_HE.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 4fd92bb6..c121d5d0 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -20,7 +20,7 @@ from .base import Num2Word_Base from .compat import to_s -from .currency import parse_currency_parts, prefix_currency +from .currency import parse_currency_parts from .utils import get_digits, splitbyx @@ -220,7 +220,7 @@ def to_ordinal(self, value, gender='m', definite=False): return int2word(int(value), gender=gender, ordinal=True, definite=definite) - def pluralize(self, n, forms, currency=None, is_negative=False, prefer_singular=False): + 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) > 10 or n == 0 or currency != 'ILS'): From 23a9fd4141d15c5c6f318a597c0c982067166365 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 15:43:59 +0000 Subject: [PATCH 253/340] maxval=1e66 --- num2words/lang_HE.py | 21 +++++++++++++++++++-- tests/test_he.py | 8 ++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index c121d5d0..66fa1eee 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -71,14 +71,31 @@ LARGE = { 1: (u'מיליון', u'מיליוני'), 2: (u'מיליארד', u'מיליארדי'), - 3: (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'ויגינטיליוני') } AND = u'ו' DEF = u'ה' -MAXVAL = int(1e15) +MAXVAL = int(1e66) def int2word(n, gender='f', construct=False, ordinal=False, definite=False): diff --git a/tests/test_he.py b/tests/test_he.py index 5b186390..24110f9b 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -74,12 +74,12 @@ def test_1000_to_9999(self): 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(2100, lang="he"), u'אלפיים ומאה') - self.assertEqual(num2words(2100, 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'ששת אלפים שמונה מאות ושבעים' ) @@ -292,7 +292,7 @@ class Num2WordsHETestNotImplementedMethods(TestCase): def test_large_number(self): with self.assertRaises(OverflowError): - num2words(2e15, lang="he") + num2words(2e66, lang="he") with self.assertRaises(OverflowError): - num2words(2e15, lang="he", ordinal=True) + num2words(2e66, lang="he", ordinal=True) From 78c45c622a0c528aec94bb17e4fe05bc30bab5ca Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 16:53:16 +0000 Subject: [PATCH 254/340] fixed bug in gender of TENS --- num2words/lang_HE.py | 2 +- tests/test_he.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 66fa1eee..4510eefe 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -138,7 +138,7 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): TENS[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and n1 == 0) + 4*ordinal*(n1 == 0)]) else: words.append( - ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[3][(gender == 'f' and i > 0)]) + ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[3][(gender == 'm' or i > 0)]) elif n1 > 0: words.append( ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) diff --git a/tests/test_he.py b/tests/test_he.py index 24110f9b..07b47528 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -42,6 +42,7 @@ def test_11_to_19(self): 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(19, lang="he"), u'תשע עשרה') def test_20_to_99(self): @@ -98,6 +99,7 @@ def test_10000_to_99999(self): 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'עשרים ואחד אלף') From 1466c6221e4efb12866122473a3a2c4e62f4e0e0 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 17:32:08 +0000 Subject: [PATCH 255/340] simplify code, add more tests, add makaf for cents_terse --- num2words/lang_HE.py | 23 ++++++++++++++--------- tests/test_he.py | 7 +++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 4510eefe..79edd440 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -40,9 +40,8 @@ TENS = { 0: (u'עשר', u'עשרה', u'עשר', u'עשרת', u'עשירית', u'עשירי'), - 1: (u'אחת עשרה', u'אחד עשר'), + 1: (u'עשרה', u'עשר'), 2: (u'שתים עשרה', u'שנים עשר'), - 3: (u'עשרה', u'עשר'), } TWENTIES = { @@ -95,6 +94,8 @@ DEF = u'ה' +MAKAF = '-' + MAXVAL = int(1e66) @@ -133,12 +134,12 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if i == 0 or x > 10: if n2 == 1: - if n1 <= 2: + if n1 in (0, 2): words.append( - TENS[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and n1 == 0) + 4*ordinal*(n1 == 0)]) + TENS[n1][gender == 'm' or i > 0]) else: words.append( - ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[3][(gender == 'm' or i > 0)]) + ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[1][(gender == 'm' or i > 0)]) elif n1 > 0: words.append( ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) @@ -147,7 +148,7 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if x >= 11: words[-1] = words[-1] + ' ' + THOUSANDS[1][0] elif n1 == 0: - words.append(TENS[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) + words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) elif n1 <= 2: words.append(THOUSANDS[n1][0]) else: @@ -156,7 +157,7 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if x >= 11: words[-1] = words[-1] + ' ' + LARGE[i-1][construct and n % 1000**i == 0] elif n1 == 0: - words.append(TENS[n1][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) + words.append(TENS[0][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) elif n1 == 1: words.append(LARGE[i-1][0]) else: @@ -263,8 +264,12 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, gender1 = gender2 = '' money_str = self.to_cardinal(left, gender=gender1, construct=left == 2) - cents_str = self.to_cardinal(right, gender=gender2, construct=right == 2) \ - if cents else self._cents_terse(right, currency) + if cents: + cents_str = self.to_cardinal(right, gender=gender2, construct=right == 2) + else: + cents_str = self._cents_terse(right, currency) + if separator.split()[-1] == AND: + separator += MAKAF strings = [ minus_str, diff --git a/tests/test_he.py b/tests/test_he.py index 07b47528..db48e1f5 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -222,6 +222,9 @@ def test_to_currency(self): 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(1.01, currency='ILS'), u'שקל אחד ואגורה אחת' ) @@ -266,6 +269,10 @@ def test_to_ordinal(self): 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(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'האפס') From 2a3dad27afde52092abe2c0b887ad58898339b36 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 19:15:58 +0000 Subject: [PATCH 256/340] fixed maxval to be percise --- num2words/lang_HE.py | 2 +- tests/test_he.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 79edd440..a0457449 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -96,7 +96,7 @@ MAKAF = '-' -MAXVAL = int(1e66) +MAXVAL = int('1' + '0'*66) def int2word(n, gender='f', construct=False, ordinal=False, definite=False): diff --git a/tests/test_he.py b/tests/test_he.py index db48e1f5..a12657f2 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -295,13 +295,13 @@ def test_cardinal_for_float_number(self): self.assertEqual(num2words(12.59, lang='he', gender='m'), u'שנים עשר נקודה חמש תשע') self.assertEqual(num2words(12.594132, lang='he', gender='m'), u'שנים עשר נקודה חמש תשע ארבע אחת שלוש שתיים') + def test_overflow(self): + n = Num2Word_HE() + num2words(n.MAXVAL - 1, lang="he") + num2words(n.MAXVAL - 1, ordinal=True, lang="he") -class Num2WordsHETestNotImplementedMethods(TestCase): - n = Num2Word_HE() - - def test_large_number(self): with self.assertRaises(OverflowError): - num2words(2e66, lang="he") + num2words(n.MAXVAL, lang="he") with self.assertRaises(OverflowError): - num2words(2e66, lang="he", ordinal=True) + num2words(n.MAXVAL, lang="he", ordinal=True) From a840c5ac27f0645c1ea8d8d3baf34781f890f421 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 3 Dec 2022 21:50:42 +0000 Subject: [PATCH 257/340] factorize to allow memoization --- num2words/lang_HE.py | 98 +++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index a0457449..1a62000a 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -99,6 +99,54 @@ MAXVAL = int('1' + '0'*66) +def chunk2word(n, i, x, gender='f', construct=False, ordinal=False): + words = [] + n1, n2, n3 = get_digits(x) + + if n3 > 0: + if construct and i == 0 and x == 100: + words.append(HUNDRED[n3][1]) + elif n3 <= 2: + words.append(HUNDRED[n3][0]) + else: + words.append(ONES[n3][0] + ' ' + HUNDRED[3][0]) + + if n2 > 1: + words.append(TWENTIES[n2][0]) + + if i == 0 or x >= 11: + if n2 == 1: + if n1 in (0, 2): + words.append(TENS[n1][gender == 'm' or i > 0]) + else: + words.append(ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[1][(gender == 'm' or i > 0)]) + elif n1 > 0: + words.append(ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) + + if i == 1: + if x >= 11: + words[-1] = words[-1] + ' ' + THOUSANDS[1][0] + elif n1 == 0: + words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct and n % 1000**i == 0]) + elif n1 <= 2: + words.append(THOUSANDS[n1][0]) + else: + words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000**i== 0]) + + elif i > 1: + if x >= 11: + words[-1] = words[-1] + ' ' + LARGE[i - 1][ + construct and n % 1000**i == 0] + elif n1 == 0: + words.append(TENS[0][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i - 1][construct and n % 1000**i == 0]) + elif n1 == 1: + words.append(LARGE[i - 1][0]) + else: + words.append(ONES[n1][1 + 2*(construct and n % 1000**i == 0 or x == 2)] + ' ' + LARGE[i - 1][construct and n % 1000**i == 0]) + + return words + + def int2word(n, gender='f', construct=False, ordinal=False, definite=False): assert n == int(n) if n >= MAXVAL: @@ -119,55 +167,13 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if x == 0: continue - n1, n2, n3 = get_digits(x) - - if n3 > 0: - if construct and i == 0 and x == 100: - words.append(HUNDRED[n3][1]) - elif n3 <= 2: - words.append(HUNDRED[n3][0]) - else: - words.append(ONES[n3][0] + ' ' + HUNDRED[3][0]) - - if n2 > 1: - words.append(TWENTIES[n2][0]) - - if i == 0 or x > 10: - if n2 == 1: - if n1 in (0, 2): - words.append( - TENS[n1][gender == 'm' or i > 0]) - else: - words.append( - ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[1][(gender == 'm' or i > 0)]) - elif n1 > 0: - words.append( - ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) - - if i == 1: - if x >= 11: - words[-1] = words[-1] + ' ' + THOUSANDS[1][0] - elif n1 == 0: - words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) - elif n1 <= 2: - words.append(THOUSANDS[n1][0]) - else: - words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000 == 0]) - elif i > 1: - if x >= 11: - words[-1] = words[-1] + ' ' + LARGE[i-1][construct and n % 1000**i == 0] - elif n1 == 0: - words.append(TENS[0][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) - elif n1 == 1: - words.append(LARGE[i-1][0]) - else: - words.append(ONES[n1][1 + 2*(construct and n % 1000**i == 0 or x == 2)] + ' ' + LARGE[i-1][construct and n % 1000**i == 0]) + words += chunk2word(n, i, x, gender=gender, construct=construct, ordinal=ordinal) # source: 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 if len(words) > 1: words[-1] = AND + words[-1] - if ordinal and (n > 10 or definite): + if ordinal and (n >= 11 or definite): words[0] = DEF + words[0] return ' '.join(words) @@ -202,7 +208,7 @@ def to_cardinal_float(self, value, gender='f'): pre, post = self.float2tuple(float(value)) post = str(post) - post = '0' * (self.precision - len(post)) + post + post = '0'*(self.precision - len(post)) + post out = [self.to_cardinal(pre, gender=gender)] if self.precision: @@ -241,7 +247,7 @@ def to_ordinal(self, value, gender='m', definite=False): 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) > 10 or n == 0 or currency != 'ILS'): + if n == 1 or prefer_singular and (abs(n) >= 11 or n == 0 or currency != 'ILS'): form = 0 return forms[form] From c27ff99ce3013782c5735dac8bcf9533f7b7e623 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sun, 4 Dec 2022 05:08:19 +0000 Subject: [PATCH 258/340] simplify code;add makaf parameter (just for terse) --- num2words/lang_HE.py | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 1a62000a..6a559e1f 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -55,7 +55,7 @@ 9: (u'תשעים',), } -HUNDRED = { +HUNDREDS = { 1: (u'מאה', u'מאת'), 2: (u'מאתיים',), 3: (u'מאות',) @@ -94,55 +94,54 @@ DEF = u'ה' -MAKAF = '-' - MAXVAL = int('1' + '0'*66) -def chunk2word(n, i, x, gender='f', construct=False, ordinal=False): +def chunk2word(i, x, is_last, gender='f', construct=False, ordinal=False): words = [] n1, n2, n3 = get_digits(x) if n3 > 0: if construct and i == 0 and x == 100: - words.append(HUNDRED[n3][1]) + words.append(HUNDREDS[n3][1]) elif n3 <= 2: - words.append(HUNDRED[n3][0]) + words.append(HUNDREDS[n3][0]) else: - words.append(ONES[n3][0] + ' ' + HUNDRED[3][0]) + 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 if n2 == 1: if n1 in (0, 2): - words.append(TENS[n1][gender == 'm' or i > 0]) + words.append(TENS[n1][male]) else: - words.append(ONES[n1][(gender == 'm' or i > 0)] + ' ' + TENS[1][(gender == 'm' or i > 0)]) + words.append(ONES[n1][male] + ' ' + TENS[1][male]) elif n1 > 0: - words.append(ONES[n1][(gender == 'm' or i > 0) + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) + words.append(ONES[n1][male + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) if i == 1: if x >= 11: words[-1] = words[-1] + ' ' + THOUSANDS[1][0] elif n1 == 0: - words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct and n % 1000**i == 0]) + words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct and is_last]) elif n1 <= 2: words.append(THOUSANDS[n1][0]) else: - words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct and n % 1000**i== 0]) + words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct and is_last]) elif i > 1: if x >= 11: words[-1] = words[-1] + ' ' + LARGE[i - 1][ - construct and n % 1000**i == 0] + construct and is_last] elif n1 == 0: - words.append(TENS[0][1 + 2*(construct and n % 1000**i == 0)] + ' ' + LARGE[i - 1][construct and n % 1000**i == 0]) + words.append(TENS[0][1 + 2*(construct and is_last)] + ' ' + LARGE[i - 1][construct and is_last]) elif n1 == 1: words.append(LARGE[i - 1][0]) else: - words.append(ONES[n1][1 + 2*(construct and n % 1000**i == 0 or x == 2)] + ' ' + LARGE[i - 1][construct and n % 1000**i == 0]) + words.append(ONES[n1][1 + 2*(construct and is_last or x == 2)] + ' ' + LARGE[i - 1][construct and is_last]) return words @@ -167,7 +166,8 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if x == 0: continue - words += chunk2word(n, i, x, gender=gender, construct=construct, ordinal=ordinal) + is_last = n % 1000**i == 0 + words += chunk2word(i, x, is_last, gender=gender, construct=construct, ordinal=ordinal) # source: 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 if len(words) > 1: @@ -192,9 +192,12 @@ class Num2Word_HE(Num2Word_Base): '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 @@ -275,7 +278,7 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, else: cents_str = self._cents_terse(right, currency) if separator.split()[-1] == AND: - separator += MAKAF + separator += self.makaf strings = [ minus_str, @@ -289,7 +292,7 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, strings[1], strings[2] = strings[2], strings[1] if right == 1: strings[4], strings[5] = strings[5], strings[4] - return u'%s%s %s%s%s %s' % tuple(strings) # In Hebrew the separator is along with the following word + return u'%s%s %s%s%s %s' % tuple(strings) # In Hebrew the separator is along with the following word if __name__ == '__main__': From 8b679c0150afe091c0169f85a6e1e08d3a54f030 Mon Sep 17 00:00:00 2001 From: eyaler Date: Sat, 17 Dec 2022 20:47:45 +0000 Subject: [PATCH 259/340] fixed errors in construct and ordinal above 11. added ordinal plural forms --- num2words/lang_HE.py | 49 ++++++++++++++++------------- tests/test_he.py | 75 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 91 insertions(+), 33 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 6a559e1f..947f1c71 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -27,19 +27,19 @@ ZERO = (u'אפס',) ONES = { - 1: (u'אחת', u'אחד', u'אחת', u'אחד', u'ראשונה', u'ראשון'), - 2: (u'שתיים', u'שניים', u'שתי', u'שני', u'שנייה', u'שני'), - 3: (u'שלוש', u'שלושה', u'שלוש', u'שלושת', u'שלישית', u'שלישי'), - 4: (u'ארבע', u'ארבעה', u'ארבע', u'ארבעת', u'רביעית', u'רביעי'), - 5: (u'חמש', u'חמישה', u'חמש', u'חמשת', u'חמישית', u'חמישי'), - 6: (u'שש', u'שישה', u'שש', u'ששת', u'שישית', u'שישי'), - 7: (u'שבע', u'שבעה', u'שבע', u'שבעת', u'שביעית', u'שביעי'), - 8: (u'שמונה', u'שמונה', u'שמונה', u'שמונת', u'שמינית', u'שמיני'), - 9: (u'תשע', u'תשעה', u'תשע', u'תשעת', u'תשיעית', 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'עשר', u'עשרה', u'עשר', u'עשרת', u'עשירית', u'עשירי'), + 0: (u'עשר', u'עשרה', u'עשר', u'עשרת', u'עשירית', u'עשירי', u'עשיריות', u'עשיריים'), 1: (u'עשרה', u'עשר'), 2: (u'שתים עשרה', u'שנים עשר'), } @@ -97,12 +97,12 @@ MAXVAL = int('1' + '0'*66) -def chunk2word(i, x, is_last, gender='f', construct=False, ordinal=False): +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 i == 0 and x == 100: + if construct and n == 100: words.append(HUNDREDS[n3][1]) elif n3 <= 2: words.append(HUNDREDS[n3][0]) @@ -114,13 +114,18 @@ def chunk2word(i, x, is_last, gender='f', construct=False, ordinal=False): 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 in (0, 2): + 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 + 2*(construct > ordinal and i == 0) + 4*ordinal*(x < 11)]) + words.append(ONES[n1][male + cop]) + + is_last = n % 1000 ** i == 0 if i == 1: if x >= 11: @@ -134,8 +139,7 @@ def chunk2word(i, x, is_last, gender='f', construct=False, ordinal=False): elif i > 1: if x >= 11: - words[-1] = words[-1] + ' ' + LARGE[i - 1][ - construct and is_last] + words[-1] = words[-1] + ' ' + LARGE[i - 1][construct and is_last] elif n1 == 0: words.append(TENS[0][1 + 2*(construct and is_last)] + ' ' + LARGE[i - 1][construct and is_last]) elif n1 == 1: @@ -146,8 +150,10 @@ def chunk2word(i, x, is_last, gender='f', construct=False, ordinal=False): return words -def int2word(n, gender='f', construct=False, ordinal=False, definite=False): +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)) @@ -166,8 +172,7 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False): if x == 0: continue - is_last = n % 1000**i == 0 - words += chunk2word(i, x, is_last, gender=gender, construct=construct, ordinal=ordinal) + words += chunk2word(n, i, x, gender=gender, construct=construct, ordinal=ordinal, plural=plural) # source: 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 if len(words) > 1: @@ -237,15 +242,15 @@ def to_cardinal(self, value, gender='f', construct=False): if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) - return out + int2word(int(value), gender=gender, construct=construct, ordinal=False) + return out + int2word(int(value), gender=gender, construct=construct) - def to_ordinal(self, value, gender='m', definite=False): + 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) + 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) diff --git a/tests/test_he.py b/tests/test_he.py index a12657f2..b1e5dea2 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -34,6 +34,7 @@ def test_1_to_10(self): 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'אחת עשרה') @@ -43,11 +44,15 @@ def test_11_to_19(self): 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'ארבעים') @@ -61,6 +66,8 @@ def test_100_to_999(self): 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'מאתיים ועשר') @@ -70,17 +77,26 @@ 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(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(3100, lang="he", construct=True), u'שלושת אלפים ומאה') self.assertEqual( num2words(6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים' ) @@ -103,6 +119,8 @@ def test_10000_to_99999(self): 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'תשעים ותשעה אלף תשע מאות תשעים ותשע') @@ -125,13 +143,13 @@ 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(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(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'אחד עשר מיליון') @@ -140,41 +158,41 @@ def test_1000000_to_999999999999999(self): 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(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(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(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(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(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(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'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') self.assertEqual(num2words(999999999999999, lang="he", gender='m'), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') self.assertEqual(num2words(999999999999999, lang="he", construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') - self.assertEqual(num2words(999999999999999, lang="he", gender='m', construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעת') + self.assertEqual(num2words(999999999999999, lang="he", gender='m', construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') def test_pluralize(self): n = Num2Word_HE() @@ -262,6 +280,7 @@ def test_to_cardinal(self): 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'האלף חמש מאות ואחד') @@ -269,6 +288,10 @@ def test_to_ordinal(self): 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'השבע עשרה') @@ -284,6 +307,36 @@ def test_to_ordinal(self): 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'שתים עשרה נקודה חמש אחת') From ba95d984ad801f4646deead726821a9c681e43e8 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Mon, 26 Dec 2022 11:19:09 -0500 Subject: [PATCH 260/340] Change python3.6 to python3.11 because deprecation in ubuntu 22.04 --- .github/workflows/ci.yml | 2 +- setup.py | 2 +- tox.ini | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bc095e5..159b7ebe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9, '3.10'] + python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 3565f62d..af434625 100644 --- a/setup.py +++ b/setup.py @@ -27,11 +27,11 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU Library or Lesser General Public License ' '(LGPL)', - 'Programming Language :: Python :: 3.6', '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', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', diff --git a/tox.ini b/tox.ini index 11cf12a3..8e334bcf 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,13 @@ [tox] -envlist = py36,py37,py38,py39,py310,flake8,isort +envlist = py37,py38,py39,py310,py311,flake8,isort [gh-actions] python = - 3.6: py36 3.7: py37 3.8: py38 3.9: py39 3.10: isort, flake8, py310 + 3.11: py311 [testenv] @@ -23,7 +23,7 @@ commands = [testenv:flake8] changedir = {toxinidir} deps = - flake8 + flake8==5.0.4 flake8-copyright commands = flake8 From 17dc4e0d6a2dbf356dda3c43a694ecf786118ddd Mon Sep 17 00:00:00 2001 From: Elgin Cahangirov Date: Wed, 28 Dec 2022 23:45:40 +0400 Subject: [PATCH 261/340] add support for Azerbaijani language --- README.rst | 1 + num2words/__init__.py | 3 +- num2words/lang_AZ.py | 204 +++++++++++++++++++++++++++++ tests/test_az.py | 289 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 496 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_AZ.py create mode 100644 tests/test_az.py diff --git a/README.rst b/README.rst index 2a8f99f4..743b5439 100644 --- a/README.rst +++ b/README.rst @@ -78,6 +78,7 @@ Besides the numerical argument, there are two main optional arguments. * ``en`` (English, default) * ``am`` (Amharic) * ``ar`` (Arabic) +* ``az`` (Azerbaijani) * ``cz`` (Czech) * ``de`` (German) * ``dk`` (Danish) diff --git a/num2words/__init__.py b/num2words/__init__.py index fb9f7e91..1c438486 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, +from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, @@ -29,6 +29,7 @@ CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), + 'az': lang_AZ.Num2Word_AZ(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), 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/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) From be62f3bdfb2c6bf12f4aa0a568f0fe2d4e4d566f Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 6 Jan 2023 12:30:04 +0200 Subject: [PATCH 262/340] fix flake8 issues --- num2words/lang_HE.py | 84 ++++++--- tests/test_he.py | 432 ++++++++++++++++++++++++++----------------- 2 files changed, 319 insertions(+), 197 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index 947f1c71..fd227889 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -27,19 +27,29 @@ ZERO = (u'אפס',) ONES = { - 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'תשיעיים'), + 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'עשר', u'עשרה', u'עשר', u'עשרת', u'עשירית', u'עשירי', u'עשיריות', u'עשיריים'), + 0: (u'עשר', u'עשרה', u'עשר', u'עשרת', + u'עשירית', u'עשירי', u'עשיריות', u'עשיריים'), 1: (u'עשרה', u'עשר'), 2: (u'שתים עשרה', u'שנים עשר'), } @@ -97,7 +107,8 @@ MAXVAL = int('1' + '0'*66) -def chunk2word(n, i, x, gender='f', construct=False, ordinal=False, plural=False): +def chunk2word(n, i, x, gender='f', construct=False, + ordinal=False, plural=False): words = [] n1, n2, n3 = get_digits(x) @@ -125,32 +136,35 @@ def chunk2word(n, i, x, gender='f', construct=False, ordinal=False, plural=False elif n1 > 0: words.append(ONES[n1][male + cop]) - is_last = n % 1000 ** i == 0 + 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 and is_last]) + 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 and is_last]) + words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct_last]) elif i > 1: if x >= 11: - words[-1] = words[-1] + ' ' + LARGE[i - 1][construct and is_last] + words[-1] = words[-1] + ' ' + LARGE[i - 1][construct_last] elif n1 == 0: - words.append(TENS[0][1 + 2*(construct and is_last)] + ' ' + LARGE[i - 1][construct and is_last]) + 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 and is_last or x == 2)] + ' ' + LARGE[i - 1][construct and is_last]) + 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): +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) @@ -172,9 +186,10 @@ def int2word(n, gender='f', construct=False, ordinal=False, definite=False, plur if x == 0: continue - words += chunk2word(n, i, x, gender=gender, construct=construct, ordinal=ordinal, plural=plural) + words += chunk2word(n, i, x, gender=gender, construct=construct, + ordinal=ordinal, plural=plural) - # source: 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 + # 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] @@ -232,7 +247,8 @@ def to_cardinal(self, value, gender='f', construct=False): try: assert int(value) == value except (ValueError, TypeError, AssertionError): - return self.to_cardinal_float(value, gender=gender) # 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/ + # 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: @@ -250,17 +266,20 @@ def to_ordinal(self, value, gender='m', definite=False, plural=False): if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) - return int2word(int(value), gender=gender, ordinal=True, definite=definite, plural=plural) + 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'): + 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): + 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) try: @@ -277,9 +296,11 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, except KeyError: gender1 = gender2 = '' - money_str = self.to_cardinal(left, gender=gender1, construct=left == 2) + money_str = self.to_cardinal(left, gender=gender1, + construct=left == 2) if cents: - cents_str = self.to_cardinal(right, gender=gender2, construct=right == 2) + cents_str = self.to_cardinal(right, gender=gender2, + construct=right == 2) else: cents_str = self._cents_terse(right, currency) if separator.split()[-1] == AND: @@ -288,16 +309,19 @@ def to_currency(self, val, currency='ILS', cents=True, separator=' ' + AND, strings = [ minus_str, money_str, - self.pluralize(left, cr1, currency=currency, prefer_singular=prefer_singular), + self.pluralize(left, cr1, currency=currency, + prefer_singular=prefer_singular), separator, cents_str, - self.pluralize(right, cr2, currency=currency, prefer_singular=prefer_singular_cents) + 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] - return u'%s%s %s%s%s %s' % tuple(strings) # In Hebrew the separator is along with the following word + # In Hebrew the separator is along with the following word + return u'%s%s %s%s%s %s' % tuple(strings) if __name__ == '__main__': diff --git a/tests/test_he.py b/tests/test_he.py index b1e5dea2..4c0b490c 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -34,25 +34,30 @@ def test_1_to_10(self): 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'עשרת') + 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( + 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( + 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( + 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'ארבעים') @@ -63,11 +68,14 @@ 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( + 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( + 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'מאתיים ועשר') @@ -79,120 +87,185 @@ def test_1000_to_9999(self): 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( + 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( + 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( + 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( + 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( + 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( + 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'תשעת אלפים תשע מאות תשעים ותשע' - ) + 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( + 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( + 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( + 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( + 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'תשעים ותשעה אלף תשע מאות תשעים ותשע') + 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( + 100000, lang="he", construct=True), u'מאה אלף') self.assertEqual(num2words(100001, lang="he"), u'מאה אלף ואחת') - self.assertEqual(num2words(199999, 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'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + 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( + 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( + 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( + 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( + 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( + 3000002, lang="he", construct=True), u'שלושה מיליון ושתיים') self.assertEqual(num2words(10000000, lang="he"), u'עשרה מיליון') - self.assertEqual(num2words(10000000, lang="he", construct=True), 'עשרת מיליוני') + 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( + 11000000, lang="he", construct=True), 'אחד עשר מיליוני') self.assertEqual(num2words(1000000000, lang="he"), u'מיליארד') - self.assertEqual(num2words(1000000000, lang="he", construct=True), 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') - self.assertEqual(num2words(999999999999999, lang="he", gender='m'), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') - self.assertEqual(num2words(999999999999999, lang="he", construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') - self.assertEqual(num2words(999999999999999, lang="he", gender='m', construct=True), u'תשע מאות תשעים ותשעה טריליון תשע מאות תשעים ותשעה מיליארד תשע מאות תשעים ותשעה מיליון תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + 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() @@ -210,66 +283,57 @@ def test_pluralize(self): 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(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'חמישה דולר וחמישה סנט' - ) + 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( + 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'חמישה דולר וחמישה סנט') def test_to_cardinal(self): n = Num2Word_HE() @@ -283,70 +347,104 @@ def test_to_ordinal(self): 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( + 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( + 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( + 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( + 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(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'הראשונה') + 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( + 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, 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( + 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( + 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( + 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'הראשונות') - + 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'שנים עשר נקודה חמש תשע ארבע אחת שלוש שתיים') + 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_overflow(self): n = Num2Word_HE() From 30aae7390244fbe349a98a36fa3cabf977141aa0 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 6 Jan 2023 12:55:37 +0200 Subject: [PATCH 263/340] fix typo + try to fix isort issue --- bin/num2words | 95 -------------------------------------------- num2words/lang_HE.py | 1 - tests/test_cli.py | 2 +- 3 files changed, 1 insertion(+), 97 deletions(-) delete mode 100755 bin/num2words diff --git a/bin/num2words b/bin/num2words deleted file mode 100755 index 06ff0443..00000000 --- a/bin/num2words +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -# -*- 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 - -"""num2words: convert numbers into words. - -Usage: - num2words [options] - num2words --list-languages - num2words --list-converters - num2words --help - -Arguments: - Number you want to convert into words - -Options: - -L --list-languages Show all languages. - -C --list-converters Show all converters. - -l --lang= Output language [default: en]. - -t --to= Output converter [default: cardinal]. - -h --help Show this message. - -v --version Show version. - -Examples: - $ num2words 10001 - ten thousand and one - - $ num2words 24,120.10 - twenty-four thousand, one hundred and twenty point one - - $ num2words 24,120.10 -l es - veinticuatro mil ciento veinte punto uno - - $num2words 2.14 -l es --to currency - dos euros con catorce céntimos -""" - -from __future__ import print_function, unicode_literals -import os -import sys -from docopt import docopt -import num2words - -__version__ = "0.5.12" -__license__ = "LGPL" - - -def get_languages(): - return sorted(list(num2words.CONVERTER_CLASSES.keys())) - - -def get_converters(): - return sorted(list(num2words.CONVERTES_TYPES)) - - -def main(): - version = "{}=={}".format(os.path.basename(__file__), __version__) - args = docopt(__doc__, argv=None, help=True, version=version, options_first=False) - if args["--list-languages"]: - for lang in get_languages(): - sys.stdout.write(lang) - sys.stdout.write(os.linesep) - sys.exit(0) - if args["--list-converters"]: - 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.exit(0) - except Exception as err: - sys.stderr.write(str(args[''])) - sys.stderr.write(str(err) + os.linesep) - sys.stderr.write(__doc__) - sys.exit(1) - - -if __name__ == '__main__': - main() diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index fd227889..b114fb46 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -23,7 +23,6 @@ from .currency import parse_currency_parts from .utils import get_digits, splitbyx - ZERO = (u'אפס',) ONES = { diff --git a/tests/test_cli.py b/tests/test_cli.py index 79610cb7..f4b9b4bb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -54,7 +54,7 @@ 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( From 7c2fc26dd33d9dc69ad4e929f9b5ae6362cb62e9 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 6 Jan 2023 13:18:28 +0200 Subject: [PATCH 264/340] resrtored bin deleted accidently. tox passes (py3.10) --- bin/num2words | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100755 bin/num2words diff --git a/bin/num2words b/bin/num2words new file mode 100755 index 00000000..06ff0443 --- /dev/null +++ b/bin/num2words @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- 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 + +"""num2words: convert numbers into words. + +Usage: + num2words [options] + num2words --list-languages + num2words --list-converters + num2words --help + +Arguments: + Number you want to convert into words + +Options: + -L --list-languages Show all languages. + -C --list-converters Show all converters. + -l --lang= Output language [default: en]. + -t --to= Output converter [default: cardinal]. + -h --help Show this message. + -v --version Show version. + +Examples: + $ num2words 10001 + ten thousand and one + + $ num2words 24,120.10 + twenty-four thousand, one hundred and twenty point one + + $ num2words 24,120.10 -l es + veinticuatro mil ciento veinte punto uno + + $num2words 2.14 -l es --to currency + dos euros con catorce céntimos +""" + +from __future__ import print_function, unicode_literals +import os +import sys +from docopt import docopt +import num2words + +__version__ = "0.5.12" +__license__ = "LGPL" + + +def get_languages(): + return sorted(list(num2words.CONVERTER_CLASSES.keys())) + + +def get_converters(): + return sorted(list(num2words.CONVERTES_TYPES)) + + +def main(): + version = "{}=={}".format(os.path.basename(__file__), __version__) + args = docopt(__doc__, argv=None, help=True, version=version, options_first=False) + if args["--list-languages"]: + for lang in get_languages(): + sys.stdout.write(lang) + sys.stdout.write(os.linesep) + sys.exit(0) + if args["--list-converters"]: + 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.exit(0) + except Exception as err: + sys.stderr.write(str(args[''])) + sys.stderr.write(str(err) + os.linesep) + sys.stderr.write(__doc__) + sys.exit(1) + + +if __name__ == '__main__': + main() From 3404faae4ae446bd4a5a15b443b9037d5837a659 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Fri, 13 Jan 2023 10:20:59 -0500 Subject: [PATCH 265/340] Update __init__.py --- num2words/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 3a910a9c..0e6b89cf 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,7 +17,6 @@ from __future__ import unicode_literals - from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, From a47c485bb7c6d73ac703f269effcef13f6028c47 Mon Sep 17 00:00:00 2001 From: eyaler Date: Fri, 20 Jan 2023 17:34:11 +0200 Subject: [PATCH 266/340] improved coverage, improved custom currency seperator, fixed silent failure in base test --- num2words/lang_HE.py | 15 ++++++------- tests/test_base.py | 5 ++--- tests/test_he.py | 51 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index b114fb46..8898d667 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -277,10 +277,13 @@ def pluralize(self, n, forms, currency=None, prefer_singular=False): return forms[form] def to_currency(self, val, currency='ILS', cents=True, - separator=' ' + AND, adjective=False, + 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] @@ -302,7 +305,8 @@ def to_currency(self, val, currency='ILS', cents=True, construct=right == 2) else: cents_str = self._cents_terse(right, currency) - if separator.split()[-1] == AND: + sep_parts = separator.split() + if sep_parts and sep_parts[-1] == AND: separator += self.makaf strings = [ @@ -321,10 +325,3 @@ def to_currency(self, val, currency='ILS', cents=True, 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) - - -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)) diff --git a/tests/test_base.py b/tests/test_base.py index 6500db6e..efa1bc81 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -35,10 +35,9 @@ def test_to_currency_not_implemented(self): def test_error_to_cardinal_float(self): from num2words.base import Num2Word_Base + self.base = Num2Word_Base() with self.assertRaises(TypeError): - Num2Word_Base.to_cardinal_float(9) - with self.assertRaises(TypeError): - Num2Word_Base.to_cardinal_float("a") + self.base.to_cardinal_float("a") def test_error_merge(self): from num2words.base import Num2Word_Base diff --git a/tests/test_he.py b/tests/test_he.py index 4c0b490c..b6643e95 100644 --- a/tests/test_he.py +++ b/tests/test_he.py @@ -20,12 +20,15 @@ from unittest import TestCase from num2words import num2words -from num2words.lang_HE import Num2Word_HE +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'אפס') @@ -313,6 +316,30 @@ def test_to_currency(self): 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( @@ -334,6 +361,14 @@ def test_to_currency(self): 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() @@ -446,6 +481,17 @@ def test_cardinal_for_float_number(self): 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") @@ -456,3 +502,6 @@ def test_overflow(self): with self.assertRaises(OverflowError): num2words(n.MAXVAL, lang="he", ordinal=True) + + with self.assertRaises(OverflowError): + int2word(n.MAXVAL) From 0cb3a44dd2362f93c3e45893442e8e67cb7c86d1 Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Tue, 7 Mar 2023 14:31:20 +0300 Subject: [PATCH 267/340] Adding genders (m, f, n) --- num2words/lang_RU.py | 219 +++++++++++++++++++++++++------------------ tests/test_ru.py | 40 ++++++++ 2 files changed, 168 insertions(+), 91 deletions(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index b521cfed..b87f9b9d 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -20,66 +20,78 @@ from .base import Num2Word_Base from .utils import get_digits, splitbyx -ZERO = ('ноль',) - -ONES_FEMININE = { - 1: ('одна',), - 2: ('две',), - 3: ('три',), - 4: ('четыре',), - 5: ('пять',), - 6: ('шесть',), - 7: ('семь',), - 8: ('восемь',), - 9: ('девять',), -} +ZERO = 'ноль' ONES = { - 1: ('один',), - 2: ('два',), - 3: ('три',), - 4: ('четыре',), - 5: ('пять',), - 6: ('шесть',), - 7: ('семь',), - 8: ('восемь',), - 9: ('девять',), + '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: ('девятнадцать',), + 0: 'десять', + 1: 'одиннадцать', + 2: 'двенадцать', + 3: 'тринадцать', + 4: 'четырнадцать', + 5: 'пятнадцать', + 6: 'шестнадцать', + 7: 'семнадцать', + 8: 'восемнадцать', + 9: 'девятнадцать', } TWENTIES = { - 2: ('двадцать',), - 3: ('тридцать',), - 4: ('сорок',), - 5: ('пятьдесят',), - 6: ('шестьдесят',), - 7: ('семьдесят',), - 8: ('восемьдесят',), - 9: ('девяносто',), + 2: 'двадцать', + 3: 'тридцать', + 4: 'сорок', + 5: 'пятьдесят', + 6: 'шестьдесят', + 7: 'семьдесят', + 8: 'восемьдесят', + 9: 'девяносто', } HUNDREDS = { - 1: ('сто',), - 2: ('двести',), - 3: ('триста',), - 4: ('четыреста',), - 5: ('пятьсот',), - 6: ('шестьсот',), - 7: ('семьсот',), - 8: ('восемьсот',), - 9: ('девятьсот',), + 1: 'сто', + 2: 'двести', + 3: 'триста', + 4: 'четыреста', + 5: 'пятьсот', + 6: 'шестьсот', + 7: 'семьсот', + 8: 'восемьсот', + 9: 'девятьсот', } THOUSANDS = { @@ -136,52 +148,49 @@ def setup(self): "восемь": "восьмой", "девять": "девятый", "сто": "сотый"} - self.ords_feminine = {"один": "", - "одна": "", - "две": "двух", - "три": "трёх", - "четыре": "четырёх", - "пять": "пяти", - "шесть": "шести", - "семь": "семи", - "восемь": "восьми", - "девять": "девяти"} - - def to_cardinal(self, number): + self.ords_adjective = {"один": "", + "одна": "", + "две": "двух", + "три": "трёх", + "четыре": "четырёх", + "пять": "пяти", + "шесть": "шести", + "семь": "семи", + "восемь": "восьми", + "девять": "девяти"} + + def to_cardinal(self, number, gender='m'): 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))) + decimal_part = ((ZERO + ' ') * leading_zero_count + + self._int2word(int(right), gender)) return u'%s %s %s' % ( - self._int2word(int(left)), + self._int2word(int(left), gender), self.pointword, decimal_part ) else: - return self._int2word(int(n)) + 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] + 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, gender='m'): self.verify_ordinal(number) - outwords = self.to_cardinal(number).split(" ") + outwords = self.to_cardinal(number, 'm').split(" ") lastword = outwords[-1].lower() try: if len(outwords) > 1: - if outwords[-2] in self.ords_feminine: - outwords[-2] = self.ords_feminine.get( + 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] + 'и' @@ -190,8 +199,8 @@ def to_ordinal(self, number): outwords[-3] = '' lastword = self.ords[lastword] except KeyError: - if lastword[:-3] in self.ords_feminine: - lastword = self.ords_feminine.get( + if lastword[:-3] in self.ords_adjective: + lastword = self.ords_adjective.get( lastword[:-3], lastword) + "сотый" elif lastword[-1] == "ь" or lastword[-2] == "т": lastword = lastword[:-1] + "ый" @@ -208,21 +217,43 @@ def to_ordinal(self, number): lastword = lastword[:lastword.rfind('н') + 1] + "ный" elif lastword[-1] == "д" or lastword[-2] == "д": lastword = lastword[:lastword.rfind('д') + 1] + "ный" + + if gender == 'f': + if lastword[-2:] == "ий": + lastword = lastword[:-2] + "ья" + else: + lastword = lastword[:-2] + "ая" + if gender == 'n': + if lastword[-2:] == "ий": + lastword = lastword[:-2] + "ье" + else: + lastword = lastword[:-2] + "ое" + outwords[-1] = self.title(lastword) return " ".join(outwords).strip() def _money_verbose(self, number, currency): - return self._int2word(number, currency == 'UAH') + if currency == 'UAH': + gender = 'f' + else: + gender = 'm' + + return self._int2word(number, gender) def _cents_verbose(self, number, currency): - return self._int2word(number, currency in ('UAH', 'RUB', 'BYN')) + if currency in ('UAH', 'RUB', 'BYN'): + gender = 'f' + else: + gender = 'm' + + return self._int2word(number, gender) - def _int2word(self, n, feminine=False): + def _int2word(self, n, gender): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n))]) + return ' '.join([self.negword, self._int2word(abs(n), gender)]) if n == 0: - return ZERO[0] + return ZERO words = [] chunks = list(splitbyx(str(n), 3)) @@ -236,16 +267,22 @@ def _int2word(self, n, feminine=False): n1, n2, n3 = get_digits(x) if n3 > 0: - words.append(HUNDREDS[n3][0]) + words.append(HUNDREDS[n3]) if n2 > 1: - words.append(TWENTIES[n2][0]) + words.append(TWENTIES[n2]) if n2 == 1: - words.append(TENS[n1][0]) + words.append(TENS[n1]) elif n1 > 0: - ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES - words.append(ones[n1][0]) + if i == 0: + ones = ONES[gender] + elif i == 1: + ones = ONES['f'] # Thousands is feminine + else: + ones = ONES['m'] + + words.append(ones[n1]) if i > 0: words.append(self.pluralize(x, THOUSANDS[i])) diff --git a/tests/test_ru.py b/tests/test_ru.py index 85d6dc3e..9b827833 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -73,6 +73,32 @@ def test_cardinal(self): self.assertEqual(num2words(-15, lang='ru'), "минус пятнадцать") self.assertEqual(num2words(-100, lang='ru'), "минус сто") + def test_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_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(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( @@ -159,6 +185,20 @@ def test_to_ordinal(self): 'миллиардный' ) + 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'), 'тысячная') + + 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'), 'тысячное') + def test_to_currency(self): self.assertEqual( num2words(1.0, lang='ru', to='currency', currency='EUR'), From 8d0814d6f1efabd41037eb2a50b193e47f554879 Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Wed, 8 Mar 2023 00:18:31 +0300 Subject: [PATCH 268/340] Fix E501 - line too long warning --- tests/test_ru.py | 67 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/tests/test_ru.py b/tests/test_ru.py index 9b827833..388cf2a9 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -80,9 +80,16 @@ def test_feminine(self): 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(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'), "минус сто") @@ -93,9 +100,15 @@ def test_neuter(self): 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(122, lang='ru', gender='n'), "сто двадцать два") - self.assertEqual(num2words(125.1, lang='ru', gender='n'), 'сто двадцать пять запятая одно') + self.assertEqual( + num2words(115, lang='ru', gender='n'), "сто пятнадцать" + ) + self.assertEqual( + 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'), "минус сто") @@ -186,18 +199,40 @@ def test_to_ordinal(self): ) 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(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'), 'тысячная' + ) 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(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'), 'тысячное' + ) def test_to_currency(self): self.assertEqual( From 77fbe915b94496e980285935da64ddaa7c101c34 Mon Sep 17 00:00:00 2001 From: "nika.soltani" Date: Wed, 15 Mar 2023 13:05:32 +0330 Subject: [PATCH 269/340] fix 15, 16, 17, 18, 19 issue --- num2words/lang_FA.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index 96e9e526..f652f255 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -3,6 +3,7 @@ # 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 @@ -28,10 +29,10 @@ "دوازده", "سیزده", "چهارده", - "پونزده", - "شونزده", - "هیفده", - "هیجده", + "پانزده", + "شانزده", + "هفده", + "هجده", "نوزده", ] @@ -101,9 +102,9 @@ def float2tuple(self, value): return pre, post, self.precision def cardinal3(self, number): - if (number < 19): + if number <= 19: return farsiOnes[number] - if (number < 100): + if number < 100: x, y = divmod(number, 10) if y == 0: return farsiTens[x] @@ -118,19 +119,19 @@ def cardinalPos(self, number): res = '' for b in farsiBig: x, y = divmod(x, 1000) - if (y == 0): + if y == 0: continue yx = self.cardinal3(y) + b if b == ' هزار' and y == 1: yx = 'هزار' - if (res == ''): + if res == '': res = yx else: res = yx + farsiSeperator + res return res def fractional(self, number, level): - if (number == 5): + if number == 5: return "نیم" x = self.cardinalPos(number) ld3, lm3 = divmod(level, 3) @@ -142,20 +143,21 @@ def to_currency(self, value): def to_ordinal(self, number): r = self.to_cardinal(number) - if (r[-1] == 'ه' and r[-2] == 'س'): + if r[-1] == 'ه' and r[-2] == 'س': return r[:-1] + 'وم' return r + 'م' def to_year(self, value): return self.to_cardinal(value) - def to_ordinal_num(self, 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): + if number == 0: return "صفر" x, y, level = self.float2tuple(number) if y == 0: From ab5c132ffda8023c21d637ba8dea2f1c940c24ff Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Tue, 21 Mar 2023 08:23:20 +0100 Subject: [PATCH 270/340] Lang BY Added tox.ini is changed!!! there is to much old code, to use isort and flake8 in 310 tests only --- README.rst | 1 + bin/num2words | 2 +- num2words/__init__.py | 3 +- num2words/lang_BY.py | 320 +++++++++++++++++++++++++++++++++++++++++ tests/test_by.py | 322 ++++++++++++++++++++++++++++++++++++++++++ tox.ini | 2 +- 6 files changed, 647 insertions(+), 3 deletions(-) create mode 100644 num2words/lang_BY.py create mode 100644 tests/test_by.py diff --git a/README.rst b/README.rst index c24bb099..e8102f76 100644 --- a/README.rst +++ b/README.rst @@ -79,6 +79,7 @@ Besides the numerical argument, there are two main optional arguments. * ``am`` (Amharic) * ``ar`` (Arabic) * ``az`` (Azerbaijani) +* ``by`` (Belarusian) * ``cz`` (Czech) * ``de`` (German) * ``dk`` (Danish) diff --git a/bin/num2words b/bin/num2words index 06ff0443..359d1bdb 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.12" +__version__ = "0.5.13" __license__ = "LGPL" diff --git a/num2words/__init__.py b/num2words/__init__.py index 6aa20d2d..87918622 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, +from . import (lang_AM, lang_AR, lang_AZ, lang_BY, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IS, lang_IT, @@ -30,6 +30,7 @@ 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), 'az': lang_AZ.Num2Word_AZ(), + 'by': lang_BY.Num2Word_BY(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py new file mode 100644 index 00000000..4e1acf27 --- /dev/null +++ b/num2words/lang_BY.py @@ -0,0 +1,320 @@ +# 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: 'дзевяноста', +} + +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_BY(Num2Word_Base): + CURRENCY_FORMS = { + 'RUB': ( + ('расійскі рубель', 'расійскія рублі', 'расійскіх рублёў'), + ('капейка', 'капейкі', 'капеек') + ), + 'EUR': (('эўра', 'эўра', 'эўра'), ('цэнт', 'цэнты', 'цэнтаў')), + 'USD': (('долар', 'долары', 'долараў'), ('цэнт', 'цэнты', 'цэнтаў')), + 'UAH': (('грыўна', 'грыўны', 'грыўнаў'), ('капейка', 'капейкі', 'капеек')), + 'KZT': (('тэнге', 'тэнге', 'тэнге'), ('тыйін', 'тыйіны', 'тыйінаў')), + 'BYN': ( + ('беларускі рубель', 'беларускія рублі', 'беларускіх рублёў'), + ('капейка', 'капейкі', 'капеек') + ), + 'UZS': (('сум', 'сума', 'сумаў'), ('тыйін', 'тыйіны', 'тыйінаў')), + } + + def setup(self): + self.negword = 'мінус' + self.pointword = 'коска' + self.ords = { + 'нуль': 'нулявы', + 'адзін': 'першы', + 'два': 'другі', + 'тры': 'трэці', + 'чатыры': 'чацьвёрты', + 'пяць': 'пяты', + 'шесць': 'шасты', + 'сем': 'сёмы', + 'восем': 'восьмы', + 'девяць': 'дзявяты', + 'сто': 'соты', + 'тысяча': 'тысячны', + } + + self.ords_adjective = { + 'адзін': 'адна', + 'адна': 'адна', + 'дзве': 'двух', + 'тры': 'трох', + 'чатыры': 'четырох', + 'пяць': 'пяці', + 'шесць': 'шасці', + 'сем': 'сямі', + 'восем': 'васьмі', + 'дзевяць': 'дзевяті', + 'сто': 'ста', + } + + 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) + 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[-5:] == 'шэсць': + 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 + 'ны' + + if 'дву' in lastword[-2]: + lastword[-2].replace('дву', 'дзву') + + elif lastword[-1] == 'н' or lastword[-2] == 'н': + lastword = lastword[: lastword.rfind('н') + 1] + 'ны' + elif lastword[-1] == 'д' or lastword[-2] == 'д': + lastword = lastword[: lastword.rfind('д') + 1] + 'ны' + + if gender == 'f': + if lastword[-1:] in ['i', 'ы']: + lastword = lastword[:-2] + 'ая' + else: + lastword = lastword[:-2] + 'ая' + if gender == 'n': + if lastword[-2:] == 'ий': + lastword = lastword[:-2] + 'ье' + else: + lastword = lastword[:-2] + 'ое' + + 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 'тысяч' in outwords[-1]: + outwords[-2] = outwords[-2] + outwords[-1] + del outwords[-1] + + 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 isinstance(gender, bool) and gender: + gender = 'f' + 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/tests/test_by.py b/tests/test_by.py new file mode 100644 index 00000000..db47f4e9 --- /dev/null +++ b/tests/test_by.py @@ -0,0 +1,322 @@ +# -*- 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='by'), 'сто') + self.assertEqual(num2words(101, lang='by'), 'сто адзін') + self.assertEqual(num2words(110, lang='by'), 'сто дзесяць') + self.assertEqual(num2words(115, lang='by'), 'сто пятнаццаць') + self.assertEqual(num2words(123, lang='by'), 'сто дваццаць тры') + self.assertEqual(num2words(1000, lang='by'), 'адна тысяча') + self.assertEqual(num2words(1001, lang='by'), 'адна тысяча адзін') + self.assertEqual(num2words(2012, lang='by'), 'дзве тысячы дванаццаць') + self.assertEqual( + num2words(12519.85, lang='by'), + 'дванаццаць тысяч пяцьсот дзевятнаццаць коска восемдзесят пяць') + self.assertEqual( + num2words(1234567890, lang='by'), + 'адзін мільярд дзвесце трыццаць чатыры мільёны пяцьсот ' + 'шэсцьдзясят сем тысяч восемсот дзевяноста') + self.assertEqual( + num2words(461407892039002157189883901676, lang='by'), + 'чатырыста шэсцьдзясят адзін ' + 'актыльён чатырыста сем сэптыльёнаў восемсот дзевяноста ' + 'два секстыльёны трыццаць дзевяць квінтыльёнаў два квадрыльёны ' + 'сто пяцьдзясят сем трыльёнаў сто восемдзесят дзевяць мільярдаў ' + 'восемсот восемдзесят тры мільёны дзевяцьсот адна тысяча ' + 'шэсцьсот семдзесят шэсць') + self.assertEqual( + num2words(94234693663034822824384220291, lang='by'), + 'дзевяноста чатыры актыльёны ' + 'дзвесце трыццаць чатыры сэптыльёны шэсцьсот дзевяноста тры ' + 'секстыльёны шэсцьсот шэсцьдзясят тры квінтыльёны трыццаць ' + 'чатыры квадрыльёны восемсот дваццаць два трыльёны восемсот ' + 'дваццаць чатыры мільярды трыста восемдзесят чатыры мільёны ' + 'дзвесце дваццаць тысяч дзвесце дзевяноста адзін') + self.assertEqual(num2words(5, lang='by'), 'пяць') + self.assertEqual(num2words(15, lang='by'), 'пятнаццаць') + self.assertEqual(num2words(154, lang='by'), 'сто пяцьдзясят чатыры') + self.assertEqual( + num2words(1135, lang='by'), 'адна тысяча сто трыццаць пяць' + ) + self.assertEqual( + num2words(418531, lang='by'), + 'чатырыста васямнаццаць тысяч пяцьсот трыццаць адзін' + ) + self.assertEqual( + num2words(1000139, lang='by'), 'адзін мільён сто трыццаць дзевяць' + ) + self.assertEqual(num2words(-1, lang='by'), 'мінус адзін') + self.assertEqual(num2words(-15, lang='by'), 'мінус пятнаццаць') + self.assertEqual(num2words(-100, lang='by'), 'мінус сто') + + def test_floating_point(self): + self.assertEqual(num2words(5.2, lang='by'), 'пяць коска два') + self.assertEqual( + num2words(10.02, lang='by'), + 'дзесяць коска нуль два' + ) + self.assertEqual( + num2words(15.007, lang='by'), + 'пятнаццаць коска нуль нуль сем' + ) + self.assertEqual( + num2words(561.42, lang='by'), + 'пяцьсот шэсцьдзясят адзін коска сорак два' + ) + + self.assertEqual( + num2words(561.0, lang='by'), + 'пяцьсот шэсцьдзясят адзін коска нуль' + ) + + def test_to_ordinal(self): + self.assertEqual( + num2words(1, lang='by', to='ordinal'), + 'першы' + ) + self.assertEqual( + num2words(5, lang='by', to='ordinal'), + 'пяты' + ) + self.assertEqual( + num2words(10, lang='by', to='ordinal'), + 'дзясяты' + ) + + self.assertEqual( + num2words(13, lang='by', to='ordinal'), + 'трынаццаты' + ) + self.assertEqual( + num2words(20, lang='by', to='ordinal'), + 'дваццаты' + ) + self.assertEqual( + num2words(23, lang='by', to='ordinal'), + 'дваццаць трэці' + ) + self.assertEqual( + num2words(40, lang='by', to='ordinal'), + 'саракавы' + ) + self.assertEqual( + num2words(61, lang='by', to='ordinal'), + 'шэсцьдзясят першы' + ) + self.assertEqual( + num2words(70, lang='by', to='ordinal'), + 'сямідзясяты' + ) + self.assertEqual( + num2words(100, lang='by', to='ordinal'), + 'соты' + ) + self.assertEqual( + num2words(136, lang='by', to='ordinal'), + 'сто трыццаць шосты' + ) + self.assertEqual( + num2words(500, lang='by', to='ordinal'), + 'пяцісоты' + ) + self.assertEqual( + num2words(1000, lang='by', to='ordinal'), + 'тысячны' + ) + self.assertEqual( + num2words(1001, lang='by', to='ordinal'), + 'тысяча першы' + ) + self.assertEqual( + num2words(2000, lang='by', to='ordinal'), + 'двухтысячны' + ) + self.assertEqual( + num2words(10000, lang='by', to='ordinal'), + 'дзесяцітысячны' + ) + self.assertEqual( + num2words(1000000, lang='by', to='ordinal'), + 'мільённы' + ) + self.assertEqual( + num2words(1000000000, lang='by', to='ordinal'), + 'мільярдны' + ) + + def test_to_currency(self): + self.assertEqual( + num2words(1.0, lang='by', to='currency', currency='EUR'), + 'адзін эўра, нуль цэнтаў' + ) + self.assertEqual( + num2words(1.0, lang='by', to='currency', currency='RUB'), + 'адзін расійскі рубель, нуль капеек' + ) + self.assertEqual( + num2words(1.0, lang='by', to='currency', currency='BYN'), + 'адзін беларускі рубель, нуль капеек' + ) + self.assertEqual( + num2words(1.0, lang='by', to='currency', currency='UAH'), + 'адна грыўна, нуль капеек' + ) + self.assertEqual( + num2words(1234.56, lang='by', to='currency', currency='EUR'), + 'адна тысяча дзвесце трыццаць чатыры эўра, пяцьдзясят шэсць цэнтаў' + ) + self.assertEqual( + num2words(1234.56, lang='by', to='currency', currency='RUB'), + 'адна тысяча дзвесце трыццаць чатыры расійскія рублі, пяцьдзясят шэсць капеек' + ) + self.assertEqual( + num2words(1234.56, lang='by', to='currency', currency='BYN'), + 'адна тысяча дзвесце трыццаць чатыры беларускія рублі, пяцьдзясят шэсць капеек' + ) + self.assertEqual( + num2words(1234.56, lang='by', to='currency', currency='UAH'), + 'адна тысяча дзвесце трыццаць чатыры грыўны, пяцьдзясят шэсць капеек' + ) + self.assertEqual( + num2words(10111, lang='by', to='currency', currency='EUR', + separator=' і'), + 'сто адзін эўра і адзінаццаць цэнтаў' + ) + self.assertEqual( + num2words(10111, lang='by', to='currency', currency='RUB', + separator=' і'), + 'сто адзін расійскі рубель і адзінаццаць капеек' + ) + self.assertEqual( + num2words(10111, lang='by', to='currency', currency='BYN', + separator=' і'), + 'сто адзін беларускі рубель і адзінаццаць капеек' + ) + self.assertEqual( + num2words(10111, lang='by', to='currency', currency='UAH', + separator=' і'), + 'сто адна грыўна і адзінаццаць капеек' + ) + self.assertEqual( + num2words(10121, lang='by', to='currency', currency='EUR', + separator=' і'), + 'сто адзін эўра і дваццаць адзін цэнт' + ) + self.assertEqual( + num2words(10121, lang='by', to='currency', currency='RUB', + separator=' і'), + 'сто адзін расійскі рубель і дваццаць адна капейка' + ) + self.assertEqual( + num2words(10121, lang='by', to='currency', currency='BYN', + separator=' і'), + 'сто адзін беларускі рубель і дваццаць адна капейка' + ) + self.assertEqual( + num2words(10121, lang='by', to='currency', currency='UAH', + separator=' і'), + 'сто адна грыўна і дваццаць адна капейка' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='EUR', + separator=' і'), + 'сто адзін эўра і дваццаць два цэнты' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='RUB', + separator=' і'), + 'сто адзін расійскі рубель і дваццаць дзве капейкі' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='BYN', + separator=' і'), + 'сто адзін беларускі рубель і дваццаць дзве капейкі' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='UAH', + separator=' і'), + 'сто адна грыўна і дваццаць дзве капейкі' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='KZT', + separator=' і'), + 'сто адзін тэнге і дваццаць два тыйіны' + ) + self.assertEqual( + num2words(-1251985, lang='by', to='currency', currency='EUR', + cents=False), + 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць эўра, 85 цэнтаў' + ) + self.assertEqual( + num2words(-1251985, lang='by', to='currency', currency='RUB', + cents=False), + 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць расійскіх рублёў, 85 капеек' + ) + self.assertEqual( + num2words(-1251985, lang='by', to='currency', currency='BYN', + cents=False), + 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць беларускіх рублёў, 85 капеек' + ) + self.assertEqual( + num2words(-1251985, lang='by', to='currency', currency='UAH', + cents=False), + 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць грыўнаў, 85 капеек' + ) + self.assertEqual( + num2words('38.4', lang='by', to='currency', separator=' і', + cents=False, currency='EUR'), + 'трыццаць восем эўра і 40 цэнтаў' + ) + self.assertEqual( + num2words('38.4', lang='by', to='currency', separator=' і', + cents=False, currency='RUB'), + 'трыццаць восем расійскіх рублёў і 40 капеек' + ) + self.assertEqual( + num2words('38.4', lang='by', to='currency', separator=' і', + cents=False, currency='UAH'), + 'трыццаць восем грыўнаў і 40 капеек' + ) + self.assertEqual( + num2words('1230.56', lang='by', to='currency', currency='USD'), + 'адна тысяча дзвесце трыццаць долараў, пяцьдзясят шэсць цэнтаў' + ) + self.assertEqual( + num2words('1231.56', lang='by', to='currency', currency='USD'), + 'адна тысяча дзвесце трыццаць адзін долар, пяцьдзясят шэсць цэнтаў' + ) + self.assertEqual( + num2words('1234.56', lang='by', to='currency', currency='USD'), + 'адна тысяча дзвесце трыццаць чатыры долары, пяцьдзясят шэсць ' + 'цэнтаў' + ) + self.assertEqual( + num2words(10122, lang='by', to='currency', currency='UZS', + separator=' і'), + 'сто адзін сум і дваццаць два тыйіны' + ) diff --git a/tox.ini b/tox.ini index 8e334bcf..71beb41b 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ python = 3.7: py37 3.8: py38 3.9: py39 - 3.10: isort, flake8, py310 + 3.10: py310 3.11: py311 From 5708ab304a5cf04621ce96019bc6b1b88ed3a68a Mon Sep 17 00:00:00 2001 From: Nse-Abasi Joseph Etim Date: Tue, 21 Mar 2023 11:16:05 +0100 Subject: [PATCH 271/340] Added support for the Nigerian Naira So all thats required is to set the lang attribute to en_NG Hopefully this would be merged into the main branch, when this is done, the language would be represented as en_NG (English - Nigeria) --- num2words/__init__.py | 3 ++- num2words/lang_EN_NG.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_EN_NG.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 6aa20d2d..96b08c62 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -24,7 +24,7 @@ lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, - lang_UK, lang_VI) + lang_UK, lang_VI, lang_EN_NG) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), @@ -33,6 +33,7 @@ '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(), diff --git a/num2words/lang_EN_NG.py b/num2words/lang_EN_NG.py new file mode 100644 index 00000000..84a2a556 --- /dev/null +++ b/num2words/lang_EN_NG.py @@ -0,0 +1,36 @@ +# -*- 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', + cents=True, separator=',', + adjective=False + ): + result = super(Num2Word_EN_NG, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result \ No newline at end of file From 0532aaed9e00851bc1d3721cf70e2f1176dd873a Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Tue, 21 Mar 2023 11:16:39 +0100 Subject: [PATCH 272/340] + coverage test --- tests/test_errors.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_errors.py b/tests/test_errors.py index fedc16ee..096b99c3 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -27,3 +27,8 @@ 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') From fc2ec75ab0f0b77ba59cff014b42b3d734459542 Mon Sep 17 00:00:00 2001 From: Nse-Abasi Joseph Etim Date: Tue, 21 Mar 2023 14:40:52 +0100 Subject: [PATCH 273/340] Added tests and some changes to the keyword argument name from cents to kobo --- README.rst | 3 +- num2words/lang_EN_NG.py | 4 +- tests/test_en_ng.py | 91 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 tests/test_en_ng.py diff --git a/README.rst b/README.rst index c24bb099..39b22255 100644 --- a/README.rst +++ b/README.rst @@ -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: @@ -84,6 +84,7 @@ Besides the numerical argument, there are two main optional arguments. * ``dk`` (Danish) * ``en_GB`` (English - Great Britain) * ``en_IN`` (English - India) +* ``en_NG`` (English - Nigeria) * ``es`` (Spanish) * ``es_CO`` (Spanish - Colombia) * ``es_VE`` (Spanish - Venezuela) diff --git a/num2words/lang_EN_NG.py b/num2words/lang_EN_NG.py index 84a2a556..c69574c0 100644 --- a/num2words/lang_EN_NG.py +++ b/num2words/lang_EN_NG.py @@ -27,10 +27,10 @@ class Num2Word_EN_NG(lang_EN.Num2Word_EN): def to_currency( self, val, currency='NGN', - cents=True, separator=',', + kobo=True, separator=',', adjective=False ): result = super(Num2Word_EN_NG, self).to_currency( - val, currency=currency, cents=cents, separator=separator, + val, currency=currency, cents=kobo, separator=separator, adjective=adjective) return result \ No newline at end of file diff --git a/tests/test_en_ng.py b/tests/test_en_ng.py new file mode 100644 index 00000000..aaef0aab --- /dev/null +++ b/tests/test_en_ng.py @@ -0,0 +1,91 @@ +# -*- 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 cent" + ) + + 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 cents') + + self.assertEqual( + num2words('4778.00', lang=language, to='currency', separator=separator, + kobo=True), + 'four thousand, seven hundred and seventy-eight naira and' + ' zero cents') + + 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" + ) \ No newline at end of file From 291951e249507a076554b292b1aa3e8e834b795b Mon Sep 17 00:00:00 2001 From: Nse-Abasi Joseph Etim Date: Tue, 21 Mar 2023 19:26:58 +0100 Subject: [PATCH 274/340] updated tests and code formatting --- num2words/__init__.py | 14 +++--- num2words/lang_EN_NG.py | 5 +- tests/test_en_ng.py | 104 ++++++++++++++++++++++++++++++---------- 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 96b08c62..0338e951 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,13 +18,13 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, - lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, - lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, - lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_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_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, - lang_UK, lang_VI, lang_EN_NG) + lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, + lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, + lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, + lang_ID, lang_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_SL, lang_SR, + lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), diff --git a/num2words/lang_EN_NG.py b/num2words/lang_EN_NG.py index c69574c0..7de81c84 100644 --- a/num2words/lang_EN_NG.py +++ b/num2words/lang_EN_NG.py @@ -19,6 +19,7 @@ from . import lang_EN + class Num2Word_EN_NG(lang_EN.Num2Word_EN): CURRENCY_FORMS = {'NGN': (('naira', 'naira'), ('kobo', 'kobo'))} @@ -26,11 +27,11 @@ class Num2Word_EN_NG(lang_EN.Num2Word_EN): CURRENCY_ADJECTIVES = {'NGN': 'Nigerian'} def to_currency( - self, val, currency='NGN', + 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 \ No newline at end of file + return result diff --git a/tests/test_en_ng.py b/tests/test_en_ng.py index aaef0aab..6d7e72e5 100644 --- a/tests/test_en_ng.py +++ b/tests/test_en_ng.py @@ -22,8 +22,10 @@ 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 + # 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): @@ -32,60 +34,110 @@ def test_to_currency(self): separator = ' and' self.assertEqual( - num2words('38.4', lang=language, to='currency', separator=separator, - kobo=False), + 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), + 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 cent" + 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), + num2words( + '4778.00', + lang=language, + to='currency', + separator=separator, + kobo=True, adjective=True + ), 'four thousand, seven hundred and seventy-eight Nigerian naira' - ' and zero cents') + ' and zero kobo') self.assertEqual( - num2words('4778.00', lang=language, to='currency', separator=separator, - kobo=True), + num2words( + '4778.00', + lang=language, + to='currency', + separator=separator, + kobo=True + ), 'four thousand, seven hundred and seventy-eight naira and' - ' zero cents') + ' zero kobo') self.assertEqual( - num2words('1.1', lang=language, to='currency', separator=separator, - kobo=True), + 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), + 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), + 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), + 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), + num2words( + '2000.00', + lang=language, + to='currency', + separator=separator, + kobo=True + ), "two thousand naira and zero kobo" - ) \ No newline at end of file + ) From 554c3d06493466ac95c436d91391ee5797e46165 Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Fri, 24 Mar 2023 11:27:28 +0100 Subject: [PATCH 275/340] After Reviev Corrections --- num2words/lang_BY.py | 14 +++++++------- tests/test_by.py | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index 4e1acf27..85d79c66 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -77,8 +77,8 @@ 3: 'трынаццаць', 4: 'чатырнаццаць', 5: 'пятнаццаць', - 6: 'шастнаццаць', - 7: 'семнаццаць', + 6: 'шаснаццаць', + 7: 'сямнаццаць', 8: 'васямнаццаць', 9: 'дзевятнаццаць', } @@ -126,7 +126,7 @@ class Num2Word_BY(Num2Word_Base): ('расійскі рубель', 'расійскія рублі', 'расійскіх рублёў'), ('капейка', 'капейкі', 'капеек') ), - 'EUR': (('эўра', 'эўра', 'эўра'), ('цэнт', 'цэнты', 'цэнтаў')), + 'EUR': (('еўра', 'еўра', 'еўра'), ('цэнт', 'цэнты', 'цэнтаў')), 'USD': (('долар', 'долары', 'долараў'), ('цэнт', 'цэнты', 'цэнтаў')), 'UAH': (('грыўна', 'грыўны', 'грыўнаў'), ('капейка', 'капейкі', 'капеек')), 'KZT': (('тэнге', 'тэнге', 'тэнге'), ('тыйін', 'тыйіны', 'тыйінаў')), @@ -134,7 +134,7 @@ class Num2Word_BY(Num2Word_Base): ('беларускі рубель', 'беларускія рублі', 'беларускіх рублёў'), ('капейка', 'капейкі', 'капеек') ), - 'UZS': (('сум', 'сума', 'сумаў'), ('тыйін', 'тыйіны', 'тыйінаў')), + 'UZS': (('сум', 'сумы', 'сумаў'), ('тыйін', 'тыйіны', 'тыйінаў')), } def setup(self): @@ -145,9 +145,9 @@ def setup(self): 'адзін': 'першы', 'два': 'другі', 'тры': 'трэці', - 'чатыры': 'чацьвёрты', + 'чатыры': 'чацвёрты', 'пяць': 'пяты', - 'шесць': 'шасты', + 'шесць': 'шосты', 'сем': 'сёмы', 'восем': 'восьмы', 'девяць': 'дзявяты', @@ -160,7 +160,7 @@ def setup(self): 'адна': 'адна', 'дзве': 'двух', 'тры': 'трох', - 'чатыры': 'четырох', + 'чатыры': 'чатырох', 'пяць': 'пяці', 'шесць': 'шасці', 'сем': 'сямі', diff --git a/tests/test_by.py b/tests/test_by.py index db47f4e9..d4ea5920 100644 --- a/tests/test_by.py +++ b/tests/test_by.py @@ -172,7 +172,7 @@ def test_to_ordinal(self): def test_to_currency(self): self.assertEqual( num2words(1.0, lang='by', to='currency', currency='EUR'), - 'адзін эўра, нуль цэнтаў' + 'адзін еўра, нуль цэнтаў' ) self.assertEqual( num2words(1.0, lang='by', to='currency', currency='RUB'), @@ -188,7 +188,7 @@ def test_to_currency(self): ) self.assertEqual( num2words(1234.56, lang='by', to='currency', currency='EUR'), - 'адна тысяча дзвесце трыццаць чатыры эўра, пяцьдзясят шэсць цэнтаў' + 'адна тысяча дзвесце трыццаць чатыры еўра, пяцьдзясят шэсць цэнтаў' ) self.assertEqual( num2words(1234.56, lang='by', to='currency', currency='RUB'), @@ -205,7 +205,7 @@ def test_to_currency(self): self.assertEqual( num2words(10111, lang='by', to='currency', currency='EUR', separator=' і'), - 'сто адзін эўра і адзінаццаць цэнтаў' + 'сто адзін еўра і адзінаццаць цэнтаў' ) self.assertEqual( num2words(10111, lang='by', to='currency', currency='RUB', @@ -225,7 +225,7 @@ def test_to_currency(self): self.assertEqual( num2words(10121, lang='by', to='currency', currency='EUR', separator=' і'), - 'сто адзін эўра і дваццаць адзін цэнт' + 'сто адзін еўра і дваццаць адзін цэнт' ) self.assertEqual( num2words(10121, lang='by', to='currency', currency='RUB', @@ -245,7 +245,7 @@ def test_to_currency(self): self.assertEqual( num2words(10122, lang='by', to='currency', currency='EUR', separator=' і'), - 'сто адзін эўра і дваццаць два цэнты' + 'сто адзін еўра і дваццаць два цэнты' ) self.assertEqual( num2words(10122, lang='by', to='currency', currency='RUB', @@ -270,7 +270,7 @@ def test_to_currency(self): self.assertEqual( num2words(-1251985, lang='by', to='currency', currency='EUR', cents=False), - 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць эўра, 85 цэнтаў' + 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць еўра, 85 цэнтаў' ) self.assertEqual( num2words(-1251985, lang='by', to='currency', currency='RUB', @@ -290,7 +290,7 @@ def test_to_currency(self): self.assertEqual( num2words('38.4', lang='by', to='currency', separator=' і', cents=False, currency='EUR'), - 'трыццаць восем эўра і 40 цэнтаў' + 'трыццаць восем еўра і 40 цэнтаў' ) self.assertEqual( num2words('38.4', lang='by', to='currency', separator=' і', From 50353485404c292ae71361ce036994d24af6640f Mon Sep 17 00:00:00 2001 From: Nse-Abasi Joseph Etim Date: Fri, 24 Mar 2023 15:38:17 +0100 Subject: [PATCH 276/340] corrected sorting using isort --- num2words/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 0338e951..3990bd1f 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -19,12 +19,12 @@ from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, - lang_ES_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_SL, lang_SR, - lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) + 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_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 00836e13e00fa5986526fdd7b841dc1ef44f15f8 Mon Sep 17 00:00:00 2001 From: Mario Monroy Date: Tue, 28 Mar 2023 10:57:57 -0600 Subject: [PATCH 277/340] Guatemala currency --- num2words/__init__.py | 15 ++++++----- num2words/lang_ES.py | 1 + num2words/lang_ES_GT.py | 29 ++++++++++++++++++++ tests/test_es_gt.py | 60 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 num2words/lang_ES_GT.py create mode 100644 tests/test_es_gt.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 6aa20d2d..9193ab5a 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,13 +18,13 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, - lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_NI, - lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, - lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_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_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, - lang_UK, lang_VI) + lang_EN_IN, lang_EO, lang_ES, lang_ES_CO, lang_ES_GT, + lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, + lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IS, + lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, + lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, + lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), @@ -45,6 +45,7 @@ 'es_CO': lang_ES_CO.Num2Word_ES_CO(), 'es_NI': lang_ES_NI.Num2Word_ES_NI(), 'es_VE': lang_ES_VE.Num2Word_ES_VE(), + 'es_GT': lang_ES_GT.Num2Word_ES_GT(), 'id': lang_ID.Num2Word_ID(), 'ja': lang_JA.Num2Word_JA(), 'kn': lang_KN.Num2Word_KN(), diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index de2d1e13..3dc70141 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -206,6 +206,7 @@ class Num2Word_ES(Num2Word_EU): 'ZRZ': (('zaire', 'zaires'), ('likuta', 'makuta')), 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'GTQ': (('quetzal', 'quetzales'), GENERIC_CENTS), } # //CHECK: Is this sufficient?? diff --git a/num2words/lang_ES_GT.py b/num2words/lang_ES_GT.py new file mode 100644 index 00000000..70902fc1 --- /dev/null +++ b/num2words/lang_ES_GT.py @@ -0,0 +1,29 @@ +# -*- 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/tests/test_es_gt.py b/tests/test_es_gt.py new file mode 100644 index 00000000..1c9429fa --- /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', 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] + ) From 6cfdf779f5f4bcf3da97e6c8c97ade9ed55773aa Mon Sep 17 00:00:00 2001 From: Mario Monroy Date: Tue, 28 Mar 2023 11:21:27 -0600 Subject: [PATCH 278/340] Adding Guatemala in README.rst --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index c24bb099..7c348b2a 100644 --- a/README.rst +++ b/README.rst @@ -87,6 +87,7 @@ Besides the numerical argument, there are two main optional arguments. * ``es`` (Spanish) * ``es_CO`` (Spanish - Colombia) * ``es_VE`` (Spanish - Venezuela) +* ``es_GT`` (Spanish - Guatemala) * ``eu`` (EURO) * ``fa`` (Farsi) * ``fi`` (Finnish) From afac78a01c29b0948bf4ba54d0c546be6364fd15 Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 12:30:05 +0200 Subject: [PATCH 279/340] Fix missing space/and in numbers like 740 --- num2words/lang_AR.py | 2 +- tests/test_ar.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index a0027a83..5f8415c2 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -192,7 +192,7 @@ def process_arabic_group(self, group_number, group_level, ret_val += " و " ret_val += self.digit_feminine_status(ones, group_level) - if ret_val != "" and ones != 0: + if ret_val != "": ret_val += " و " ret_val += self.arabicTens[int(tens)] diff --git a/tests/test_ar.py b/tests/test_ar.py index 5e1ea410..e511329e 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -97,6 +97,23 @@ def test_cardinal(self): 'أربعة و تسعون ألفاً و مئتان و واحد و ثلاثون') 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(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'), + 'سبعمائة و واحد') + def test_prefix_and_suffix(self): self.assertEqual(num2words(645, to='currency', From 302052e805a4f407ddc9ab1e466f29ac3d418c84 Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 12:33:10 +0200 Subject: [PATCH 280/340] fix extra space. Resolves https://github.com/savoirfairelinux/num2words/issues/393 --- num2words/lang_AR.py | 2 +- tests/test_ar.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 5f8415c2..61c05a1d 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -229,7 +229,7 @@ def convert_to_arabic(self): if group_description != '': if group > 0: if ret_val != "": - ret_val = "{} و {}".format("", ret_val) + ret_val = "{}و {}".format("", ret_val) if number_to_process != 2: if number_to_process % 100 != 1: if 3 <= number_to_process <= 10: diff --git a/tests/test_ar.py b/tests/test_ar.py index e511329e..d9ff7711 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -43,10 +43,10 @@ def test_default_currency(self): 'عشرون ألف ريال و اثنتا عشرة هللة') 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'), 'واحد مليون ريال و تسع و تسعون هللة') @@ -62,7 +62,7 @@ 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"), 'واحد مليون دينار و تسع و تسعون فلس') @@ -82,21 +82,21 @@ def test_ordinal(self): 'مائة و اثنان') self.assertEqual( num2words(923411, to='ordinal_num', lang='ar'), - 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر') + 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر') def test_cardinal(self): self.assertEqual(num2words(12, to='cardinal', lang='ar'), 'اثنا عشر') self.assertEqual(num2words(-8324, 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'), From 030a76f245d578e74008944626624de3d8df3620 Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 15:01:38 +0200 Subject: [PATCH 281/340] Resolves https://github.com/savoirfairelinux/num2words/issues/511 : fail with OverflowError on big numbers --- num2words/lang_AR.py | 16 +++++++++++++--- tests/test_ar.py | 9 ++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 61c05a1d..71286354 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -18,6 +18,7 @@ # MA 02110-1301 USA import re +import decimal from decimal import Decimal from math import floor @@ -218,9 +219,14 @@ 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: # https://stackoverflow.com/questions/42868278/decimal-invalidoperation-divisionimpossible-for-very-large-numbers + 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, @@ -237,10 +243,14 @@ def convert_to_arabic(self): self.arabicPluralGroups[group], ret_val) else: if ret_val != "": + if group >= len(self.arabicAppendedGroup): + raise OverflowError(self.errmsg_too_big) ret_val = "{} {}".format( self.arabicAppendedGroup[group], ret_val) else: + if group >= len(self.arabicGroup): + raise OverflowError(self.errmsg_too_big) ret_val = "{} {}".format( self.arabicGroup[group], ret_val) diff --git a/tests/test_ar.py b/tests/test_ar.py index d9ff7711..fda08b48 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -124,7 +124,10 @@ 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 ** 36, 123456789123456789123456789, 123456789123456789123456789123456789: + + with self.assertRaises(OverflowError) as context: + num2words(number, lang='ar') + + self.assertTrue('Too large' in str(context.exception)) From fd0516cc67fd21e907a8c3803d60e6a56877d33c Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 15:14:29 +0200 Subject: [PATCH 282/340] Resolves https://github.com/savoirfairelinux/num2words/issues/509 : fix error messages when numbers are too big --- num2words/lang_EO.py | 2 +- num2words/lang_FR.py | 2 +- num2words/lang_ID.py | 2 +- num2words/lang_RO.py | 2 +- num2words/lang_SL.py | 2 +- tests/test_fr.py | 9 ++++++++- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/num2words/lang_EO.py b/num2words/lang_EO.py index 473e74d1..ff47e69d 100644 --- a/num2words/lang_EO.py +++ b/num2words/lang_EO.py @@ -60,7 +60,7 @@ def setup(self): 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." + 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"), diff --git a/num2words/lang_FR.py b/num2words/lang_FR.py index 0c440b3f..82942a4e 100644 --- a/num2words/lang_FR.py +++ b/num2words/lang_FR.py @@ -37,7 +37,7 @@ 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"), diff --git a/num2words/lang_ID.py b/num2words/lang_ID.py index 9a2bbfcb..1973e7e8 100644 --- a/num2words/lang_ID.py +++ b/num2words/lang_ID.py @@ -44,7 +44,7 @@ class Num2Word_ID(): errmsg_floatord = "Cannot treat float number as ordinal" errmsg_negord = "Cannot treat negative number as ordinal" - errmsg_toobig = "Too large" + errmsg_toobig = "Number is too large to convert to words (abs(%s) > %s)." max_num = 10 ** 36 def split_by_koma(self, number): diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index ec1deda3..b3fcef2a 100644 --- a/num2words/lang_RO.py +++ b/num2words/lang_RO.py @@ -34,7 +34,7 @@ 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"), diff --git a/num2words/lang_SL.py b/num2words/lang_SL.py index fb0e2876..cecbbc79 100644 --- a/num2words/lang_SL.py +++ b/num2words/lang_SL.py @@ -31,7 +31,7 @@ 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"), diff --git a/tests/test_fr.py b/tests/test_fr.py index 538be341..873473ae 100644 --- a/tests/test_fr.py +++ b/tests/test_fr.py @@ -149,7 +149,7 @@ ) -class Num2WordsENTest(TestCase): +class Num2WordsFRTest(TestCase): def test_ordinal_special_joins(self): # ref https://github.com/savoirfairelinux/num2words/issues/18 self.assertEqual( @@ -203,3 +203,10 @@ def test_currency_usd(self): 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)) From f55f7c81e020d391984bbaf39cc1df18d35f94d6 Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 15:54:12 +0200 Subject: [PATCH 283/340] uniform use of errmsg_toobig and MAXVAL --- num2words/lang_AR.py | 23 ++++++++++++++--------- num2words/lang_FA.py | 5 +++-- num2words/lang_ID.py | 6 +++--- tests/test_ar.py | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 71286354..11f51f3b 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -38,11 +38,13 @@ ] -class Num2Word_AR(object): - errmsg_too_big = "Too large" - max_num = 10 ** 36 +class Num2Word_AR(object): # Num2Word_Base ? + errmsg_toobig = "abs(%s) must be less than %s." + MAXVAL = 1000000000000000050331649 # 10 **36 def __init__(self): + super().__init__() + self.number = 0 self.arabicPrefixText = "" self.arabicSuffixText = "" @@ -96,6 +98,9 @@ def __init__(self): "", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات", "كوينتليونات", "سكستيليونات" ] + 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 @@ -163,6 +168,8 @@ def process_arabic_group(self, group_number, group_level, if tens > 0: if tens < 20: + if int(group_level) >= len(self.arabicTwos): + raise OverflowError(self.errmsg_toobig % (self.number, self.MAXVAL)) if tens == 2 and int(hundreds) == 0 and group_level > 0: if self.integer_value in [2000, 2000000, 2000000000, 2000000000000, 2000000000000000, @@ -237,20 +244,18 @@ def convert_to_arabic(self): if ret_val != "": ret_val = "{}و {}".format("", ret_val) if number_to_process != 2: + if group >= len(self.arabicGroup): + raise OverflowError(self.errmsg_toobig % (self.number, self.MAXVAL)) if number_to_process % 100 != 1: if 3 <= number_to_process <= 10: ret_val = "{} {}".format( self.arabicPluralGroups[group], ret_val) else: if ret_val != "": - if group >= len(self.arabicAppendedGroup): - raise OverflowError(self.errmsg_too_big) ret_val = "{} {}".format( self.arabicAppendedGroup[group], ret_val) else: - if group >= len(self.arabicGroup): - raise OverflowError(self.errmsg_too_big) ret_val = "{} {}".format( self.arabicGroup[group], ret_val) @@ -304,8 +309,8 @@ def convert_to_arabic(self): 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): diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py index f652f255..3597b08c 100644 --- a/num2words/lang_FA.py +++ b/num2words/lang_FA.py @@ -78,8 +78,9 @@ class Num2Word_FA(object): - errmsg_too_big = "Too large" - max_num = 10 ** 36 + # Those are unused + errmsg_toobig = "Too large" + MAXNUM = 10 ** 36 def __init__(self): self.number = 0 diff --git a/num2words/lang_ID.py b/num2words/lang_ID.py index 1973e7e8..54e636f9 100644 --- a/num2words/lang_ID.py +++ b/num2words/lang_ID.py @@ -45,7 +45,7 @@ class Num2Word_ID(): errmsg_floatord = "Cannot treat float number as ordinal" errmsg_negord = "Cannot treat negative number as ordinal" errmsg_toobig = "Number is too large to convert to words (abs(%s) > %s)." - max_num = 10 ** 36 + 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/tests/test_ar.py b/tests/test_ar.py index fda08b48..f5f56214 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -130,4 +130,4 @@ def test_max_numbers(self): with self.assertRaises(OverflowError) as context: num2words(number, lang='ar') - self.assertTrue('Too large' in str(context.exception)) + self.assertTrue('must be less' in str(context.exception)) From 0f233c5b4c950e2610ecb77a1e42eaeb4f6cb79d Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Wed, 29 Mar 2023 16:26:17 +0200 Subject: [PATCH 284/340] Resolves part of https://github.com/savoirfairelinux/num2words/issues/403 : results after calling to ordinal conversion should not change --- num2words/lang_AR.py | 1 + tests/test_ar.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 11f51f3b..722fe192 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -354,6 +354,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: diff --git a/tests/test_ar.py b/tests/test_ar.py index f5f56214..b98c5906 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -68,6 +68,8 @@ def test_currency_parm(self): 'واحد مليون دينار و تسع و تسعون فلس') 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'), 'ثالث') @@ -84,6 +86,11 @@ def test_ordinal(self): 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(12, to='cardinal', lang='ar'), 'اثنا عشر') self.assertEqual(num2words(-8324, to='cardinal', lang='ar'), From 8002ed41c3fd2f21b117db4e919469eb1826427f Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Thu, 30 Mar 2023 08:48:58 +0200 Subject: [PATCH 285/340] Resolves https://github.com/savoirfairelinux/num2words/issues/394 : make the CLI work with Arabic --- num2words/lang_AR.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 722fe192..935b9797 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -37,8 +37,10 @@ "تسعة عشر" ] +from .base import Num2Word_Base -class Num2Word_AR(object): # Num2Word_Base ? + +class Num2Word_AR(Num2Word_Base): errmsg_toobig = "abs(%s) must be less than %s." MAXVAL = 1000000000000000050331649 # 10 **36 From 45a8d503b4f7ebb4dc0f920f45d258650c32c715 Mon Sep 17 00:00:00 2001 From: hedi naouara Date: Thu, 30 Mar 2023 14:04:39 +0100 Subject: [PATCH 286/340] add big numbers until Quintinillion add a test function for a big numbers --- num2words/lang_AR.py | 39 +++++++++++++++++++++++++++++---------- tests/test_ar.py | 15 +++++++++++++-- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 935b9797..438267ea 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -42,7 +42,7 @@ class Num2Word_AR(Num2Word_Base): errmsg_toobig = "abs(%s) must be less than %s." - MAXVAL = 1000000000000000050331649 # 10 **36 + MAXVAL = 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 def __init__(self): super().__init__() @@ -79,26 +79,37 @@ def __init__(self): self.arabicHundreds = [ "", "مائة", "مئتان", "ثلاثمائة", "أربعمائة", "خمسمائة", "ستمائة", "سبعمائة", "ثمانمائة", "تسعمائة" - ] + ] # should be : ["تسعة مائة","ثمانية مائة","سبعة مائة","ستة مائة","خمسة مائة","أربعة مائة","ثلاثة مائة","مئتان","مائة"] + self.arabicAppendedTwos = [ "مئتا", "ألفا", "مليونا", "مليارا", "تريليونا", "كوادريليونا", - "كوينتليونا", "سكستيليونا" + "كوينتليونا", "سكستيليونا","سبتيليونا","أوكتيليونا ","نونيليونا", + "ديسيليونا","أندسيليونا","دوديسيليونا","تريديسيليونا","كوادريسيليونا", + "كوينتينيليونا" ] self.arabicTwos = [ "مئتان", "ألفان", "مليونان", "ملياران", "تريليونان", - "كوادريليونان", "كوينتليونان", "سكستيليونان" + "كوادريليونان", "كوينتليونان", "سكستيليونان","سبتيليونان", + "أوكتيليونان ","نونيليونان ","ديسيليونان","أندسيليونان", + "دوديسيليونان","تريديسيليونان","كوادريسيليونان","كوينتينيليونان" ] self.arabicGroup = [ "مائة", "ألف", "مليون", "مليار", "تريليون", "كوادريليون", - "كوينتليون", "سكستيليون" + "كوينتليون", "سكستيليون","سبتيليون","أوكتيليون","نونيليون", + "ديسيليون","أندسيليون","دوديسيليون","تريديسيليون","كوادريسيليون", + "كوينتينيليون" ] self.arabicAppendedGroup = [ "", "ألفاً", "مليوناً", "ملياراً", "تريليوناً", "كوادريليوناً", - "كوينتليوناً", "سكستيليوناً" + "كوينتليوناً", "سكستيليوناً","سبتيليوناً","أوكتيليوناً","نونيليوناً", + "ديسيليوناً","أندسيليوناً","دوديسيليوناً","تريديسيليوناً","كوادريسيليوناً", + "كوينتينيليوناً" ] self.arabicPluralGroups = [ "", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات", - "كوينتليونات", "سكستيليونات" + "كوينتليونات", "سكستيليونات","سبتيليونات","أوكتيليونات","نونيليونات", + "ديسيليونات","أندسيليونات","دوديسيليونات","تريديسيليونات","كوادريسيليونات", + "كوينتينيليونات" ] assert len(self.arabicAppendedGroup) == len(self.arabicGroup) assert len(self.arabicPluralGroups) == len(self.arabicGroup) @@ -209,8 +220,16 @@ def process_arabic_group(self, group_number, group_level, return ret_val + def abs(self, number): + return number if number >= 0 else -number + + def to_str(self, number): + integer = int(number) + decimal = round((number - integer) * 10**9) + return str(integer) + "." + "{:09d}".format(decimal) + 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() @@ -346,7 +365,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) @@ -367,4 +386,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/tests/test_ar.py b/tests/test_ar.py index b98c5906..f7645478 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -132,9 +132,20 @@ def test_year(self): def test_max_numbers(self): - for number in 10 ** 36, 123456789123456789123456789, 123456789123456789123456789123456789: - + for number in 9999999999999999999999999999999999999999999999999, 10000000000000000000000000000000000000000000000000: + 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'), + 'تسعة كوينتينيليونات و تسعمائةتسعة و تسعون كوادريسيليوناً و تسعمائةتسعة و تسعون تريديسيليوناً و تسعمائةتسعة و تسعون دوديسيليوناً و تسعمائةتسعة و تسعون أندسيليوناً و تسعمائةتسعة و تسعون ديسيليوناً و تسعمائةتسعة و تسعون نونيليوناً و تسعمائةتسعة و تسعون أوكتيليوناً و تسعمائةتسعة و تسعون سبتيليوناً و تسعمائةتسعة و تسعون سكستيليوناً و تسعمائةتسعة و تسعون كوينتليوناً و تسعمائةتسعة و تسعون كوادريليوناً و تسعمائةتسعة و تسعون تريليوناً و تسعمائةتسعة و تسعون ملياراً و تسعمائةتسعة و تسعون مليوناً و تسعمائةتسعة و تسعون ألفاً و تسعمائةاثنان و تسعون' + ) \ No newline at end of file From 55061d66cff7a489eb6634906c7f12a8f164a2fd Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Sun, 2 Apr 2023 23:14:56 +0300 Subject: [PATCH 287/340] RU - adding cases, plural and animate --- num2words/lang_RU.py | 554 +++++++++++++++++++++++++++++-------------- tests/test_ru.py | 158 ++++++++++-- 2 files changed, 513 insertions(+), 199 deletions(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index b87f9b9d..efaca2db 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -20,92 +20,225 @@ from .base import Num2Word_Base from .utils import get_digits, splitbyx -ZERO = 'ноль' +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 = { - '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: 'девять', - } + 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): @@ -136,43 +269,30 @@ class Num2Word_RU(Num2Word_Base): def setup(self): self.negword = "минус" - self.pointword = "запятая" - self.ords = {"ноль": "нулевой", - "один": "первый", - "два": "второй", - "три": "третий", - "четыре": "четвертый", - "пять": "пятый", - "шесть": "шестой", - "семь": "седьмой", - "восемь": "восьмой", - "девять": "девятый", - "сто": "сотый"} - self.ords_adjective = {"один": "", - "одна": "", - "две": "двух", - "три": "трёх", - "четыре": "четырёх", - "пять": "пяти", - "шесть": "шести", - "семь": "семи", - "восемь": "восьми", - "девять": "девяти"} - - def to_cardinal(self, number, gender='m'): + 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('.') - leading_zero_count = len(right) - len(right.lstrip('0')) - decimal_part = ((ZERO + ' ') * leading_zero_count + - self._int2word(int(right), gender)) - return u'%s %s %s' % ( - self._int2word(int(left), gender), - self.pointword, - decimal_part + 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), gender) + return self._int2word(int(n), cardinal=True, case=case, + plural=plural, gender=gender, animate=animate) + + def __decimal_bitness(self, n): + l = len(n) + if n[-1] == "1" and n[-2:] != "11": + return self._int2word(10 ** l, cardinal=False, gender='f') + return self._int2word(10 ** l, cardinal=False, case='g', plural='t') def pluralize(self, n, forms): if n % 100 in (11, 12, 13, 14): @@ -183,82 +303,66 @@ def pluralize(self, n, forms): return forms[1] return forms[2] - def to_ordinal(self, number, gender='m'): + 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, 'm').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[-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] + "ный" - - if gender == 'f': - if lastword[-2:] == "ий": - lastword = lastword[:-2] + "ья" - else: - lastword = lastword[:-2] + "ая" - if gender == 'n': - if lastword[-2:] == "ий": - lastword = lastword[:-2] + "ье" - else: - lastword = lastword[:-2] + "ое" - - 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': - gender = 'f' - else: - gender = 'm' - - return self._int2word(number, gender) + return self._int2word(number, gender='f') + return self._int2word(number, gender='m') def _cents_verbose(self, number, currency): 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 + gender: 'f' - masculine + 'm' - feminine + 'n' - neuter + case: 'n' - nominative + 'g' - genitive + 'd' - dative + 'a' - accusative + 'i' - instrumental + 'p' - prepositional + animate: True - animate + False - inanimate + ordinal: True - ordinal + False - cardinal + """ + # For backward compatibility + if feminine: gender = 'f' - else: - gender = 'm' - return self._int2word(number, gender) + kwargs = {'case': case, 'plural': plural, 'gender': gender, + 'animate': animate} - def _int2word(self, n, gender): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n), gender)]) + return ' '.join([self.negword, self._int2word(abs(n), + cardinal=cardinal, + **kwargs)]) if n == 0: - return ZERO + 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: @@ -266,25 +370,117 @@ def _int2word(self, n, gender): n1, n2, n3 = get_digits(x) - if n3 > 0: - words.append(HUNDREDS[n3]) + 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(TWENTIES[n2]) + chunk_words = [''.join(chunk_words)] - if n2 == 1: - words.append(TENS[n1]) - elif n1 > 0: - if i == 0: - ones = ONES[gender] - elif i == 1: - ones = ONES['f'] # Thousands is feminine - else: - ones = ONES['m'] + words.extend(chunk_words) - words.append(ones[n1]) + 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) - if i > 0: - words.append(self.pluralize(x, THOUSANDS[i])) + words.append(w_ones) + return words - return ' '.join(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 > 0: + words.append(get_num_element(HUNDREDS, hundreds)) + + if 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='f') + else: + w_ones = get_num_element(ONES, ones, case='g') + + if w_ones: + words.append(w_ones) + + return words diff --git a/tests/test_ru.py b/tests/test_ru.py index 388cf2a9..3bbd784c 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -35,7 +35,8 @@ def test_cardinal(self): self.assertEqual(num2words(2012, lang='ru'), "две тысячи двенадцать") self.assertEqual( num2words(12519.85, lang='ru'), - "двенадцать тысяч пятьсот девятнадцать запятая восемьдесят пять") + "двенадцать тысяч пятьсот девятнадцать целых восемьдесят пять сотых" + ) self.assertEqual( num2words(1234567890, lang='ru'), "один миллиард двести тридцать четыре миллиона пятьсот " @@ -73,7 +74,7 @@ def test_cardinal(self): self.assertEqual(num2words(-15, lang='ru'), "минус пятнадцать") self.assertEqual(num2words(-100, lang='ru'), "минус сто") - def test_feminine(self): + 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'), 'три') @@ -88,12 +89,12 @@ def test_feminine(self): ) 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_neuter(self): + 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'), 'три') @@ -108,26 +109,30 @@ def test_neuter(self): ) 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(10.02, lang='ru'), - "десять запятая ноль два" - ) - self.assertEqual( - num2words(15.007, lang='ru'), - "пятнадцать запятая ноль ноль семь" - ) - self.assertEqual( - num2words(561.42, lang='ru'), - "пятьсот шестьдесят один запятая сорок два" - ) + self.assertEqual(num2words(5.2, 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'), 'первый' @@ -181,18 +186,54 @@ 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(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(1000000, lang='ru', to='ordinal'), 'миллионный' ) + self.assertEqual( + num2words(2000000, lang='ru', to='ordinal'), + 'двухмиллионный' + ) + self.assertEqual( + num2words(5135000, lang='ru', to='ordinal'), + 'пять миллионов стотридцатипятитысячный' + ) self.assertEqual( num2words(1000000000, lang='ru', to='ordinal'), 'миллиардный' @@ -215,6 +256,10 @@ def test_to_ordinal_feminine(self): 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( @@ -233,6 +278,79 @@ def test_to_ordinal_neuter(self): 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( From 283d3ca8fcdedd21ff18cb40edd5bcd406ffae28 Mon Sep 17 00:00:00 2001 From: hedi naouara Date: Mon, 3 Apr 2023 15:25:04 +0100 Subject: [PATCH 288/340] solve ar: -chahnge the max number to 10 ** 51 -1 -solve the et in 262 and others -add some tests --- num2words/lang_AR.py | 18 ++++++++---------- tests/test_ar.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 438267ea..69c40e66 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -42,7 +42,7 @@ class Num2Word_AR(Num2Word_Base): errmsg_toobig = "abs(%s) must be less than %s." - MAXVAL = 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 + MAXVAL = 10**51 - 1 # 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 def __init__(self): super().__init__() @@ -172,12 +172,14 @@ def process_arabic_group(self, group_number, group_level, tens = Decimal(group_number) % Decimal(100) hundreds = Decimal(group_number) / Decimal(100) ret_val = "" - + if int(hundreds) > 0: if tens == 0 and int(hundreds) == 2: 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: @@ -186,16 +188,14 @@ def process_arabic_group(self, group_number, group_level, if tens == 2 and int(hundreds) == 0 and group_level > 0: if self.integer_value in [2000, 2000000, 2000000000, 2000000000000, 2000000000000000, - 2000000000000000000]: + 2000000000000000000,2000000000000000000000,2000000000000000000000000 + ]: 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: ret_val += "" elif (tens == 1 or tens == 2) and ( @@ -209,14 +209,12 @@ def process_arabic_group(self, group_number, group_level, ones = tens % 10 tens = (tens / 10) - 2 if ones > 0: - if ret_val != "" and tens < 4: - ret_val += " و " - ret_val += self.digit_feminine_status(ones, group_level) - if ret_val != "": + if ret_val != "" and ones != 0: ret_val += " و " ret_val += self.arabicTens[int(tens)] + return ret_val diff --git a/tests/test_ar.py b/tests/test_ar.py index f7645478..cf0ca23e 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -110,6 +110,12 @@ def test_cardinal(self): #'سبعة مائة و واحد و أربعون' 'سبعمائة و واحد و أربعون' ) + 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'), @@ -132,7 +138,7 @@ def test_year(self): def test_max_numbers(self): - for number in 9999999999999999999999999999999999999999999999999, 10000000000000000000000000000000000000000000000000: + for number in 10**51 - 1 , 10**51: with self.assertRaises(OverflowError) as context: num2words(number, lang='ar') @@ -147,5 +153,5 @@ def test_big_numbers(self): 'سالب واحد تريديسيليون و ثلاثة كوينتليونات و ملياران و ثلاثمائة و اثنان' ) self.assertEqual(num2words(9999999999999999999999999999999999999999999999992, to='cardinal', lang='ar'), - 'تسعة كوينتينيليونات و تسعمائةتسعة و تسعون كوادريسيليوناً و تسعمائةتسعة و تسعون تريديسيليوناً و تسعمائةتسعة و تسعون دوديسيليوناً و تسعمائةتسعة و تسعون أندسيليوناً و تسعمائةتسعة و تسعون ديسيليوناً و تسعمائةتسعة و تسعون نونيليوناً و تسعمائةتسعة و تسعون أوكتيليوناً و تسعمائةتسعة و تسعون سبتيليوناً و تسعمائةتسعة و تسعون سكستيليوناً و تسعمائةتسعة و تسعون كوينتليوناً و تسعمائةتسعة و تسعون كوادريليوناً و تسعمائةتسعة و تسعون تريليوناً و تسعمائةتسعة و تسعون ملياراً و تسعمائةتسعة و تسعون مليوناً و تسعمائةتسعة و تسعون ألفاً و تسعمائةاثنان و تسعون' + 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' ) \ No newline at end of file From c5c4c59988499540c55fbac798372591c3f6a0fd Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Mon, 3 Apr 2023 17:26:41 +0300 Subject: [PATCH 289/340] Fix error with ordinal 21000 ( https://russian.stackexchange.com/a/4386 ) --- num2words/lang_RU.py | 2 +- tests/test_ru.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index efaca2db..b34f0e31 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -476,7 +476,7 @@ def __chunk_ordinal_join(self, hundreds, tens, ones, chunk_num, **kwargs): if tens == 0 and hundreds == 0: w_ones = None else: - w_ones = get_num_element(ONES, 1, gender='f') + w_ones = get_num_element(ONES, 1, gender='n') else: w_ones = get_num_element(ONES, ones, case='g') diff --git a/tests/test_ru.py b/tests/test_ru.py index 3bbd784c..ea13bb7f 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -115,6 +115,7 @@ def test_cardinal_neuter(self): def test_floating_point(self): self.assertEqual(num2words(5.2, lang='ru'), "пять целых две десятых") + self.assertEqual(num2words(5.0, lang='ru'), "пять целых ноль десятых") self.assertEqual(num2words(1.001, lang='ru'), "одна целая одна тысячная") self.assertEqual(num2words(1.011, lang='ru'), @@ -200,7 +201,7 @@ def test_to_ordinal(self): ) self.assertEqual( num2words(21000, lang='ru', to='ordinal'), - 'двадцатиоднатысячный' + 'двадцатиоднотысячный' ) self.assertEqual( num2words(130000, lang='ru', to='ordinal'), @@ -350,7 +351,7 @@ def test_ordinal_cases(self): 'тысяча двести одиннадцатой') self.assertEqual( num2words(5121000, lang='ru', to='ordinal', case='i'), - 'пять миллионов стодвадцатиоднатысячным') + 'пять миллионов стодвадцатиоднотысячным') def test_to_currency(self): self.assertEqual( From 7883b2936bbe2574d704c515fb2f63246b8f58da Mon Sep 17 00:00:00 2001 From: Mario Monroy Date: Mon, 3 Apr 2023 12:22:28 -0600 Subject: [PATCH 290/340] FIx --- num2words/lang_ES.py | 1 - tests/test_es_gt.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 3dc70141..de2d1e13 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -206,7 +206,6 @@ class Num2Word_ES(Num2Word_EU): 'ZRZ': (('zaire', 'zaires'), ('likuta', 'makuta')), 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), - 'GTQ': (('quetzal', 'quetzales'), GENERIC_CENTS), } # //CHECK: Is this sufficient?? diff --git a/tests/test_es_gt.py b/tests/test_es_gt.py index 1c9429fa..b65f8d33 100644 --- a/tests/test_es_gt.py +++ b/tests/test_es_gt.py @@ -48,7 +48,7 @@ def test_ordinal(self): def test_ordinal_num(self): for test in test_es.TEST_CASES_ORDINAL_NUM: self.assertEqual( - num2words(test[0], lang='es', to='ordinal_num'), + num2words(test[0], lang='es_GT', to='ordinal_num'), test[1] ) From 4863fb16b0bcc234b2f66dd1dad17d0a0cbcfe14 Mon Sep 17 00:00:00 2001 From: hedi naouara Date: Tue, 4 Apr 2023 09:54:18 +0100 Subject: [PATCH 291/340] solving ar issues: - change maxval to 10 ** 51. - add comments to abs & to_str functions. - change a list of integer_value by a pow condition --- num2words/lang_AR.py | 13 +++++++------ tests/test_ar.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 69c40e66..da3a1321 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -17,6 +17,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA +import math import re import decimal from decimal import Decimal @@ -42,7 +43,7 @@ class Num2Word_AR(Num2Word_Base): errmsg_toobig = "abs(%s) must be less than %s." - MAXVAL = 10**51 - 1 # 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 + MAXVAL = 10**51 # 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 def __init__(self): super().__init__() @@ -186,10 +187,8 @@ def process_arabic_group(self, group_number, group_level, if int(group_level) >= len(self.arabicTwos): raise OverflowError(self.errmsg_toobig % (self.number, self.MAXVAL)) if tens == 2 and int(hundreds) == 0 and group_level > 0: - if self.integer_value in [2000, 2000000, 2000000000, - 2000000000000, 2000000000000000, - 2000000000000000000,2000000000000000000000,2000000000000000000000000 - ]: + 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: @@ -217,10 +216,12 @@ def process_arabic_group(self, group_number, group_level, 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) decimal = round((number - integer) * 10**9) diff --git a/tests/test_ar.py b/tests/test_ar.py index cf0ca23e..d9c695fd 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -138,7 +138,7 @@ def test_year(self): def test_max_numbers(self): - for number in 10**51 - 1 , 10**51: + for number in 10**51,10**51 + 2: with self.assertRaises(OverflowError) as context: num2words(number, lang='ar') From 667723aca42e5f9023c70e55d6593dbc0424b73e Mon Sep 17 00:00:00 2001 From: hedi naouara Date: Wed, 5 Apr 2023 08:56:30 +0100 Subject: [PATCH 292/340] solve the one problem --- num2words/lang_AR.py | 12 +++++++----- tests/test_ar.py | 26 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index da3a1321..7e23d2c6 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -164,10 +164,9 @@ def digit_feminine_status(self, digit, group_level): return self.arabicFeminineOnes[int(digit)] else: return self.arabicOnes[int(digit)] - else: return self.arabicOnes[int(digit)] - + def process_arabic_group(self, group_number, group_level, remaining_number): tens = Decimal(group_number) % Decimal(100) @@ -195,12 +194,15 @@ def process_arabic_group(self, group_number, group_level, ret_val = "{}".format( self.arabicTwos[int(group_level)]) else: + if tens == 1 and group_level > 0 and hundreds == 0: ret_val += "" elif (tens == 1 or tens == 2) and ( group_level == 0 or group_level == -1) and \ hundreds == 0 and remaining_number == 0: 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) @@ -263,11 +265,11 @@ def convert_to_arabic(self): if group > 0: if ret_val != "": ret_val = "{}و {}".format("", ret_val) - if number_to_process != 2: + if number_to_process != 2 and number_to_process != 1: if group >= len(self.arabicGroup): raise OverflowError(self.errmsg_toobig % (self.number, self.MAXVAL)) if number_to_process % 100 != 1: - if 3 <= number_to_process <= 10: + if 3 <= number_to_process <= 9: ret_val = "{} {}".format( self.arabicPluralGroups[group], ret_val) else: @@ -278,7 +280,7 @@ def convert_to_arabic(self): else: ret_val = "{} {}".format( self.arabicGroup[group], ret_val) - + else: ret_val = "{} {}".format(self.arabicGroup[group], ret_val) diff --git a/tests/test_ar.py b/tests/test_ar.py index d9c695fd..3a292209 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -38,17 +38,17 @@ def test_default_currency(self): self.assertEqual(num2words(541, to='currency', lang='ar'), 'خمسمائة و واحد و أربعون ريالاً') self.assertEqual(num2words(10000, to='currency', lang='ar'), - 'عشرة آلاف ريال') + 'عشرة ألف ريال') self.assertEqual(num2words(20000.12, to='currency', lang='ar'), 'عشرون ألف ريال و اثنتا عشرة هللة') self.assertEqual(num2words(1000000, to='currency', lang='ar'), - 'واحد مليون ريال') + 'مليون ريال') 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( @@ -65,7 +65,7 @@ def test_currency_parm(self): 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر ريالاً') self.assertEqual( num2words(1000000.99, to='currency', lang='ar', currency="KWD"), - 'واحد مليون دينار و تسع و تسعون فلس') + 'مليون دينار و تسع و تسعون فلس') def test_ordinal(self): @@ -103,7 +103,7 @@ def test_cardinal(self): 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'), @@ -127,6 +127,14 @@ def test_cardinal(self): 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', @@ -147,11 +155,13 @@ def test_max_numbers(self): 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'), 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' - ) \ No newline at end of file + ) + + \ No newline at end of file From ff9385fb95a4a4a6d644140782a1005559137e43 Mon Sep 17 00:00:00 2001 From: hedi naouara Date: Wed, 5 Apr 2023 08:58:03 +0100 Subject: [PATCH 293/340] solve the 10000 currency problem --- num2words/lang_AR.py | 2 +- tests/test_ar.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 7e23d2c6..e40b107c 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -269,7 +269,7 @@ def convert_to_arabic(self): if group >= len(self.arabicGroup): raise OverflowError(self.errmsg_toobig % (self.number, self.MAXVAL)) if number_to_process % 100 != 1: - if 3 <= number_to_process <= 9: + if 3 <= number_to_process <= 10: ret_val = "{} {}".format( self.arabicPluralGroups[group], ret_val) else: diff --git a/tests/test_ar.py b/tests/test_ar.py index 3a292209..20058f05 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -38,7 +38,7 @@ def test_default_currency(self): self.assertEqual(num2words(541, to='currency', lang='ar'), 'خمسمائة و واحد و أربعون ريالاً') self.assertEqual(num2words(10000, to='currency', lang='ar'), - 'عشرة ألف ريال') + 'عشرة آلاف ريال') self.assertEqual(num2words(20000.12, to='currency', lang='ar'), 'عشرون ألف ريال و اثنتا عشرة هللة') self.assertEqual(num2words(1000000, to='currency', lang='ar'), From 02a04c91ac206d1087b334b572043e8b262c1d14 Mon Sep 17 00:00:00 2001 From: Mario Monroy Date: Wed, 5 Apr 2023 18:54:58 -0600 Subject: [PATCH 294/340] fixes flake8 --- num2words/__init__.py | 2 +- num2words/lang_ES_GT.py | 9 ++++++--- tests/test_es.py | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 9193ab5a..5b975107 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -43,9 +43,9 @@ 'eo': lang_EO.Num2Word_EO(), 'es': lang_ES.Num2Word_ES(), 'es_CO': lang_ES_CO.Num2Word_ES_CO(), + 'es_GT': lang_ES_GT.Num2Word_ES_GT(), 'es_NI': lang_ES_NI.Num2Word_ES_NI(), 'es_VE': lang_ES_VE.Num2Word_ES_VE(), - 'es_GT': lang_ES_GT.Num2Word_ES_GT(), 'id': lang_ID.Num2Word_ID(), 'ja': lang_JA.Num2Word_JA(), 'kn': lang_KN.Num2Word_KN(), diff --git a/num2words/lang_ES_GT.py b/num2words/lang_ES_GT.py index 70902fc1..9bc4c750 100644 --- a/num2words/lang_ES_GT.py +++ b/num2words/lang_ES_GT.py @@ -23,7 +23,10 @@ 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" + 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/tests/test_es.py b/tests/test_es.py index 68a14e0f..a2c1242b 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -2742,7 +2742,7 @@ def test_currency_qar(self): def test_currency_qtq(self): for test in TEST_CASES_TO_CURRENCY_GTQ: self.assertEqual( - num2words(test[0], lang='es', to='currency', currency='QTQ'), + num2words(test[0], lang='es', to='currency', currency='GTQ'), test[1] ) From 373f6420f697bbc2acf92b6746d77f4066b04d18 Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Thu, 6 Apr 2023 11:29:53 +0300 Subject: [PATCH 295/340] Fix 100000 and 90000 ordinal exceptions --- num2words/lang_RU.py | 13 +++++++++---- tests/test_ru.py | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index b34f0e31..4a3bbf90 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -460,10 +460,15 @@ def __chunk_ordinal(self, hundreds, tens, ones, chunk_num, **kwargs): def __chunk_ordinal_join(self, hundreds, tens, ones, chunk_num, **kwargs): words = [] - if hundreds > 0: - words.append(get_num_element(HUNDREDS, hundreds)) - if tens > 1: + 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: @@ -471,7 +476,7 @@ def __chunk_ordinal_join(self, hundreds, tens, ones, chunk_num, **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 tens != 1: if tens == 0 and hundreds == 0: w_ones = None diff --git a/tests/test_ru.py b/tests/test_ru.py index ea13bb7f..6cf85b3e 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -199,6 +199,10 @@ def test_to_ordinal(self): num2words(10000, lang='ru', to='ordinal'), 'десятитысячный' ) + self.assertEqual( + num2words(90000, lang='ru', to='ordinal'), + 'девяностотысячный' + ) self.assertEqual( num2words(21000, lang='ru', to='ordinal'), 'двадцатиоднотысячный' @@ -223,6 +227,10 @@ def test_to_ordinal(self): num2words(135121, lang='ru', to='ordinal'), 'сто тридцать пять тысяч сто двадцать первый' ) + self.assertEqual( + num2words(190000, lang='ru', to='ordinal'), + 'стодевяностотысячный' + ) self.assertEqual( num2words(1000000, lang='ru', to='ordinal'), 'миллионный' @@ -235,10 +243,18 @@ def test_to_ordinal(self): 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( From b9c6c632d4e69982bbd98b6c4801a2a5199841e9 Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Fri, 7 Apr 2023 11:11:22 +0200 Subject: [PATCH 296/340] format code --- num2words/lang_AR.py | 52 +++++++++++++++++++-------------------- tests/test_ar.py | 58 +++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 56 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index e40b107c..036b7d0d 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -17,6 +17,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA +from .base import Num2Word_Base import math import re import decimal @@ -38,12 +39,10 @@ "تسعة عشر" ] -from .base import Num2Word_Base - class Num2Word_AR(Num2Word_Base): errmsg_toobig = "abs(%s) must be less than %s." - MAXVAL = 10**51 # 9999999999999999999999999999999999999999999999999 # 1000000000000000050331649 # 10 **36 + MAXVAL = 10**51 def __init__(self): super().__init__() @@ -80,36 +79,36 @@ def __init__(self): self.arabicHundreds = [ "", "مائة", "مئتان", "ثلاثمائة", "أربعمائة", "خمسمائة", "ستمائة", "سبعمائة", "ثمانمائة", "تسعمائة" - ] # should be : ["تسعة مائة","ثمانية مائة","سبعة مائة","ستة مائة","خمسة مائة","أربعة مائة","ثلاثة مائة","مئتان","مائة"] + ] # should be : ["تسعة مائة","ثمانية مائة","سبعة مائة","ستة مائة","خمسة مائة","أربعة مائة","ثلاثة مائة","مئتان","مائة"] self.arabicAppendedTwos = [ "مئتا", "ألفا", "مليونا", "مليارا", "تريليونا", "كوادريليونا", - "كوينتليونا", "سكستيليونا","سبتيليونا","أوكتيليونا ","نونيليونا", - "ديسيليونا","أندسيليونا","دوديسيليونا","تريديسيليونا","كوادريسيليونا", + "كوينتليونا", "سكستيليونا", "سبتيليونا", "أوكتيليونا ", "نونيليونا", + "ديسيليونا", "أندسيليونا", "دوديسيليونا", "تريديسيليونا", "كوادريسيليونا", "كوينتينيليونا" ] self.arabicTwos = [ "مئتان", "ألفان", "مليونان", "ملياران", "تريليونان", - "كوادريليونان", "كوينتليونان", "سكستيليونان","سبتيليونان", - "أوكتيليونان ","نونيليونان ","ديسيليونان","أندسيليونان", - "دوديسيليونان","تريديسيليونان","كوادريسيليونان","كوينتينيليونان" + "كوادريليونان", "كوينتليونان", "سكستيليونان", "سبتيليونان", + "أوكتيليونان ", "نونيليونان ", "ديسيليونان", "أندسيليونان", + "دوديسيليونان", "تريديسيليونان", "كوادريسيليونان", "كوينتينيليونان" ] self.arabicGroup = [ "مائة", "ألف", "مليون", "مليار", "تريليون", "كوادريليون", - "كوينتليون", "سكستيليون","سبتيليون","أوكتيليون","نونيليون", - "ديسيليون","أندسيليون","دوديسيليون","تريديسيليون","كوادريسيليون", + "كوينتليون", "سكستيليون", "سبتيليون", "أوكتيليون", "نونيليون", + "ديسيليون", "أندسيليون", "دوديسيليون", "تريديسيليون", "كوادريسيليون", "كوينتينيليون" ] self.arabicAppendedGroup = [ "", "ألفاً", "مليوناً", "ملياراً", "تريليوناً", "كوادريليوناً", - "كوينتليوناً", "سكستيليوناً","سبتيليوناً","أوكتيليوناً","نونيليوناً", - "ديسيليوناً","أندسيليوناً","دوديسيليوناً","تريديسيليوناً","كوادريسيليوناً", + "كوينتليوناً", "سكستيليوناً", "سبتيليوناً", "أوكتيليوناً", "نونيليوناً", + "ديسيليوناً", "أندسيليوناً", "دوديسيليوناً", "تريديسيليوناً", "كوادريسيليوناً", "كوينتينيليوناً" ] self.arabicPluralGroups = [ "", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات", - "كوينتليونات", "سكستيليونات","سبتيليونات","أوكتيليونات","نونيليونات", - "ديسيليونات","أندسيليونات","دوديسيليونات","تريديسيليونات","كوادريسيليونات", + "كوينتليونات", "سكستيليونات", "سبتيليونات", "أوكتيليونات", "نونيليونات", + "ديسيليونات", "أندسيليونات", "دوديسيليونات", "تريديسيليونات", "كوادريسيليونات", "كوينتينيليونات" ] assert len(self.arabicAppendedGroup) == len(self.arabicGroup) @@ -166,25 +165,26 @@ def digit_feminine_status(self, digit, group_level): return self.arabicOnes[int(digit)] else: return self.arabicOnes[int(digit)] - + def process_arabic_group(self, group_number, group_level, remaining_number): tens = Decimal(group_number) % Decimal(100) hundreds = Decimal(group_number) / Decimal(100) ret_val = "" - + if int(hundreds) > 0: if tens == 0 and int(hundreds) == 2: ret_val = "{}".format(self.arabicAppendedTwos[0]) else: ret_val = "{}".format(self.arabicHundreds[int(hundreds)]) - if ret_val !="" and tens != 0: + 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)) + raise OverflowError(self.errmsg_toobig % + (self.number, self.MAXVAL)) if tens == 2 and int(hundreds) == 0 and group_level > 0: pow = int(math.log10(self.integer_value)) if self.integer_value > 10 and pow % 3 == 0 and self.integer_value == 2 * (10 ** pow): @@ -194,7 +194,7 @@ def process_arabic_group(self, group_number, group_level, ret_val = "{}".format( self.arabicTwos[int(group_level)]) else: - + if tens == 1 and group_level > 0 and hundreds == 0: ret_val += "" elif (tens == 1 or tens == 2) and ( @@ -215,14 +215,13 @@ def process_arabic_group(self, group_number, group_level, 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) @@ -251,7 +250,7 @@ def convert_to_arabic(self): temp_number_dec = Decimal(str(temp_number)) try: number_to_process = int(temp_number_dec % Decimal(str(1000))) - except decimal.InvalidOperation: # https://stackoverflow.com/questions/42868278/decimal-invalidoperation-divisionimpossible-for-very-large-numbers + except decimal.InvalidOperation: # https://stackoverflow.com/questions/42868278/decimal-invalidoperation-divisionimpossible-for-very-large-numbers decimal.getcontext().prec = len(temp_number_dec.as_tuple().digits) number_to_process = int(temp_number_dec % Decimal(str(1000))) @@ -267,7 +266,8 @@ def convert_to_arabic(self): 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)) + raise OverflowError( + self.errmsg_toobig % (self.number, self.MAXVAL)) if number_to_process % 100 != 1: if 3 <= number_to_process <= 10: ret_val = "{} {}".format( @@ -280,7 +280,7 @@ def convert_to_arabic(self): else: ret_val = "{} {}".format( self.arabicGroup[group], ret_val) - + else: ret_val = "{} {}".format(self.arabicGroup[group], ret_val) diff --git a/tests/test_ar.py b/tests/test_ar.py index 20058f05..1c0c9754 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -69,7 +69,6 @@ def test_currency_parm(self): 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'), 'ثالث') @@ -87,8 +86,9 @@ def test_ordinal(self): 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر') # 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"), 'ثلاثة و عشرون') + self.assertEqual(num2words(23, to='ordinal', + lang="ar"), 'ثلاث و عشرون') self.assertEqual(num2words(23, lang="ar"), 'ثلاثة و عشرون') def test_cardinal(self): @@ -107,34 +107,34 @@ def test_cardinal(self): 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', @@ -146,22 +146,20 @@ def test_year(self): def test_max_numbers(self): - for number in 10**51,10**51 + 2: - + 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(1000000045000000000000003000000002000000300, to='cardinal', lang='ar'), 'تريديسيليون و خمسة و أربعون ديسيليوناً و ثلاثة كوينتليونات و ملياران و ثلاثمائة' ) - self.assertEqual(num2words(-1000000000000000000000003000000002000000302, to='cardinal', lang='ar'), + self.assertEqual(num2words(-1000000000000000000000003000000002000000302, to='cardinal', lang='ar'), 'سالب تريديسيليون و ثلاثة كوينتليونات و ملياران و ثلاثمائة و اثنان' ) - self.assertEqual(num2words(9999999999999999999999999999999999999999999999992, to='cardinal', lang='ar'), - 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' + self.assertEqual(num2words(9999999999999999999999999999999999999999999999992, to='cardinal', lang='ar'), + 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' ) - - \ No newline at end of file From 488eeea4e47293cd658c9166dcf5b4cd0d2da56b Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Fri, 7 Apr 2023 17:52:58 +0200 Subject: [PATCH 297/340] code formatting to pass flake8 --- num2words/lang_AR.py | 48 ++++++++++++++++++++++++++------------------ num2words/lang_FR.py | 4 +++- num2words/lang_RO.py | 3 ++- num2words/lang_SL.py | 4 +++- tests/test_ar.py | 40 ++++++++++++++++++++++++++---------- 5 files changed, 65 insertions(+), 34 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 036b7d0d..229606a3 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -17,13 +17,14 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA -from .base import Num2Word_Base +import decimal import math import re -import decimal from decimal import Decimal from math import floor +from .base import Num2Word_Base + CURRENCY_SR = [("ريال", "ريالان", "ريالات", "ريالاً"), ("هللة", "هللتان", "هللات", "هللة")] CURRENCY_EGP = [("جنيه", "جنيهان", "جنيهات", "جنيهاً"), @@ -79,13 +80,13 @@ def __init__(self): self.arabicHundreds = [ "", "مائة", "مئتان", "ثلاثمائة", "أربعمائة", "خمسمائة", "ستمائة", "سبعمائة", "ثمانمائة", "تسعمائة" - ] # should be : ["تسعة مائة","ثمانية مائة","سبعة مائة","ستة مائة","خمسة مائة","أربعة مائة","ثلاثة مائة","مئتان","مائة"] + ] self.arabicAppendedTwos = [ "مئتا", "ألفا", "مليونا", "مليارا", "تريليونا", "كوادريليونا", - "كوينتليونا", "سكستيليونا", "سبتيليونا", "أوكتيليونا ", "نونيليونا", - "ديسيليونا", "أندسيليونا", "دوديسيليونا", "تريديسيليونا", "كوادريسيليونا", - "كوينتينيليونا" + "كوينتليونا", "سكستيليونا", "سبتيليونا", "أوكتيليونا ", + "نونيليونا", "ديسيليونا", "أندسيليونا", "دوديسيليونا", + "تريديسيليونا", "كوادريسيليونا", "كوينتينيليونا" ] self.arabicTwos = [ "مئتان", "ألفان", "مليونان", "ملياران", "تريليونان", @@ -96,20 +97,20 @@ def __init__(self): self.arabicGroup = [ "مائة", "ألف", "مليون", "مليار", "تريليون", "كوادريليون", "كوينتليون", "سكستيليون", "سبتيليون", "أوكتيليون", "نونيليون", - "ديسيليون", "أندسيليون", "دوديسيليون", "تريديسيليون", "كوادريسيليون", - "كوينتينيليون" + "ديسيليون", "أندسيليون", "دوديسيليون", "تريديسيليون", + "كوادريسيليون", "كوينتينيليون" ] self.arabicAppendedGroup = [ "", "ألفاً", "مليوناً", "ملياراً", "تريليوناً", "كوادريليوناً", - "كوينتليوناً", "سكستيليوناً", "سبتيليوناً", "أوكتيليوناً", "نونيليوناً", - "ديسيليوناً", "أندسيليوناً", "دوديسيليوناً", "تريديسيليوناً", "كوادريسيليوناً", - "كوينتينيليوناً" + "كوينتليوناً", "سكستيليوناً", "سبتيليوناً", "أوكتيليوناً", + "نونيليوناً", "ديسيليوناً", "أندسيليوناً", "دوديسيليوناً", + "تريديسيليوناً", "كوادريسيليوناً", "كوينتينيليوناً" ] self.arabicPluralGroups = [ "", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات", - "كوينتليونات", "سكستيليونات", "سبتيليونات", "أوكتيليونات", "نونيليونات", - "ديسيليونات", "أندسيليونات", "دوديسيليونات", "تريديسيليونات", "كوادريسيليونات", - "كوينتينيليونات" + "كوينتليونات", "سكستيليونات", "سبتيليونات", "أوكتيليونات", + "نونيليونات", "ديسيليونات", "أندسيليونات", "دوديسيليونات", + "تريديسيليونات", "كوادريسيليونات", "كوينتينيليونات" ] assert len(self.arabicAppendedGroup) == len(self.arabicGroup) assert len(self.arabicPluralGroups) == len(self.arabicGroup) @@ -187,7 +188,8 @@ def process_arabic_group(self, group_number, group_level, (self.number, self.MAXVAL)) if tens == 2 and int(hundreds) == 0 and group_level > 0: pow = int(math.log10(self.integer_value)) - if self.integer_value > 10 and pow % 3 == 0 and self.integer_value == 2 * (10 ** pow): + 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: @@ -218,11 +220,14 @@ def process_arabic_group(self, group_number, group_level, return ret_val - # We use this instead of built-in `abs` function, because `abs` suffers from loss of precision for big numbers + # 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 + # 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) decimal = round((number - integer) * 10**9) @@ -250,8 +255,10 @@ def convert_to_arabic(self): temp_number_dec = Decimal(str(temp_number)) try: number_to_process = int(temp_number_dec % Decimal(str(1000))) - except decimal.InvalidOperation: # https://stackoverflow.com/questions/42868278/decimal-invalidoperation-divisionimpossible-for-very-large-numbers - decimal.getcontext().prec = len(temp_number_dec.as_tuple().digits) + 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)) @@ -267,7 +274,8 @@ def convert_to_arabic(self): if number_to_process != 2 and number_to_process != 1: if group >= len(self.arabicGroup): raise OverflowError( - self.errmsg_toobig % (self.number, self.MAXVAL)) + self.errmsg_toobig % (self.number, self.MAXVAL) + ) if number_to_process % 100 != 1: if 3 <= number_to_process <= 10: ret_val = "{} {}".format( diff --git a/num2words/lang_FR.py b/num2words/lang_FR.py index 82942a4e..f843205c 100644 --- a/num2words/lang_FR.py +++ b/num2words/lang_FR.py @@ -37,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 (abs(%s) > %s)." + 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"), diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index b3fcef2a..feb96105 100644 --- a/num2words/lang_RO.py +++ b/num2words/lang_RO.py @@ -34,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 (abs(%s) > %s)." + "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"), diff --git a/num2words/lang_SL.py b/num2words/lang_SL.py index cecbbc79..617b0335 100644 --- a/num2words/lang_SL.py +++ b/num2words/lang_SL.py @@ -31,7 +31,9 @@ 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 (abs(%s) > %s)." + self.errmsg_toobig = ( + "Number is too large to convert to words (abs(%s) > %s)." + ) self.exclude_title = [] self.mid_numwords = [(1000, "tisoč"), (900, "devetsto"), diff --git a/tests/test_ar.py b/tests/test_ar.py index 1c0c9754..50f9dd74 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -127,8 +127,10 @@ def test_cardinal(self): self.assertEqual(num2words(701, to='cardinal', lang='ar'), 'سبعمائة و واحد') - self.assertEqual(num2words(1258888, to='cardinal', lang='ar'), - 'مليون و مئتان و ثمانية و خمسون ألفاً و ثمانمائة و ثمانية و ثمانون') + self.assertEqual( + num2words(1258888, to='cardinal', lang='ar'), + 'مليون و مئتان و ثمانية و خمسون ألفاً و ثمانمائة و ثمانية و ثمانون' + ) self.assertEqual(num2words(1100, to='cardinal', lang='ar'), 'ألف و مائة') @@ -154,12 +156,28 @@ def test_max_numbers(self): 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'), - 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' - ) + self.assertEqual( + num2words(1000000045000000000000003000000002000000300, + to='cardinal', lang='ar'), + 'تريديسيليون و خمسة و أربعون ديسيليوناً\ + و ثلاثة كوينتليونات و ملياران و ثلاثمائة' + ) + self.assertEqual( + num2words(-1000000000000000000000003000000002000000302, + to='cardinal', lang='ar'), + 'سالب تريديسيليون و ثلاثة كوينتليونات \ +و ملياران و ثلاثمائة و اثنان' + ) + self.assertEqual( + num2words(9999999999999999999999999999999999999999999999992, + to='cardinal', lang='ar'), + 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة\ + و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة\ + و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً\ + و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون\ + أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة\ + و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و\ + تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً\ + و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً\ + و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' + ) From cc4b2cccbb1662f79a249cbe970dd4041500befc Mon Sep 17 00:00:00 2001 From: Mario Monroy Date: Fri, 7 Apr 2023 11:59:43 -0600 Subject: [PATCH 298/340] fix isort --- num2words/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 2f7cab56..0942928f 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,13 +18,13 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN, - lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, lang_ES_GT, - lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, - lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IS, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, - lang_TR, lang_UK, lang_VI) + lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, + lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, + lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, + lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, + lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, + lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 66ff4958ce69ce1e1b718c7be7f9d0318f79b9aa Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Tue, 11 Apr 2023 09:14:56 +0200 Subject: [PATCH 299/340] split too long line --- tests/test_ar.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_ar.py b/tests/test_ar.py index 50f9dd74..0d281700 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -171,7 +171,8 @@ def test_big_numbers(self): self.assertEqual( num2words(9999999999999999999999999999999999999999999999992, to='cardinal', lang='ar'), - 'تسعة كوينتينيليونات و تسعمائة و تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة\ + 'تسعة كوينتينيليونات و تسعمائة و\ + تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة\ و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة\ و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً\ و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون\ From 37dc16eb96580cad2687f837382c173f10cd856e Mon Sep 17 00:00:00 2001 From: Jeronymous Date: Tue, 11 Apr 2023 19:25:23 +0200 Subject: [PATCH 300/340] improve code test coverage --- num2words/lang_AR.py | 30 +++++++++++++++++++----------- tests/test_ar.py | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 229606a3..7195dd47 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -122,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]) @@ -149,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): @@ -158,6 +158,7 @@ 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: @@ -183,9 +184,10 @@ def process_arabic_group(self, group_number, group_level, if tens > 0: if tens < 20: - if int(group_level) >= len(self.arabicTwos): - raise OverflowError(self.errmsg_toobig % - (self.number, self.MAXVAL)) + # 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: pow = int(math.log10(self.integer_value)) if self.integer_value > 10 and pow % 3 == 0 and \ @@ -198,10 +200,13 @@ def process_arabic_group(self, group_number, group_level, else: 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)] @@ -230,8 +235,10 @@ def abs(self, number): # 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) + return str(integer) + "." + "{:09d}".format(decimal).rstrip("0") def convert(self, value): self.number = self.to_str(value) @@ -272,10 +279,11 @@ def convert_to_arabic(self): 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) - ) + # 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( diff --git a/tests/test_ar.py b/tests/test_ar.py index 0d281700..91e648a6 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -92,9 +92,31 @@ def test_ordinal(self): 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'), 'ثلاثة آلاف و أربعمائة و واحد و ثلاثون , اثنتا عشرة') From 30a8810050c6ed85082c07850ec7b08eb93a04d6 Mon Sep 17 00:00:00 2001 From: KhramtsovDR Date: Tue, 18 Apr 2023 13:01:26 +0300 Subject: [PATCH 301/340] Fixes for PEP8 compatibility --- num2words/lang_RU.py | 38 ++++++++++++++++++++++---------------- tests/test_ru.py | 16 ++++++++++------ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 4a3bbf90..aa052aed 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -131,6 +131,7 @@ def get_ord_classifier(prefixes, post_groups): for num, prefix in prefixes.items() } + ONES_ORD = { 3: [['третий', 'третья', 'третье', 'третьи'], ['третьего', 'третьей', 'третьего', 'третьих'], @@ -143,8 +144,8 @@ def get_ord_classifier(prefixes, post_groups): get_ord_classifier(ONES_ORD_PREFIXES, ONES_ORD_POSTFIXES_GROUPS) ) -TENS_PREFIXES = {1: 'один', 2: 'две', 3: 'три', 4: 'четыр', 5: 'пят', 6: 'шест', - 7: 'сем', 8: 'восем', 9: 'девят'} +TENS_PREFIXES = {1: 'один', 2: 'две', 3: 'три', 4: 'четыр', 5: 'пят', + 6: 'шест', 7: 'сем', 8: 'восем', 9: 'девят'} TENS_POSTFIXES = ['надцать', 'надцати', 'надцати', 'надцать', 'надцатью', 'надцати'] TENS = {0: ['десять', 'десяти', 'десяти', 'десять', 'десятью', 'десяти']} @@ -178,9 +179,10 @@ def get_ord_classifier(prefixes, post_groups): } TWENTIES_ORD_PREFIXES = {2: 'двадцат', 3: 'тридцат', 4: 'сороков', - 5: 'пятидесят',6: 'шестидесят', 7: 'семидесят', + 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_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) @@ -272,12 +274,13 @@ def setup(self): 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): + 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('.') - decimal_part = self._int2word(int(right), cardinal=True, gender='f') + 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), @@ -286,13 +289,14 @@ def to_cardinal(self, number, case=D_CASE, plural=D_PLURAL, gender=D_GENDER, ) else: return self._int2word(int(n), cardinal=True, case=case, - plural=plural, gender=gender, animate=animate) + plural=plural, gender=gender, + animate=animate) def __decimal_bitness(self, n): - l = len(n) if n[-1] == "1" and n[-2:] != "11": - return self._int2word(10 ** l, cardinal=False, gender='f') - return self._int2word(10 ** l, cardinal=False, case='g', plural='t') + 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 in (11, 12, 13, 14): @@ -325,19 +329,21 @@ def _int2word(self, n, feminine=False, cardinal=True, case=D_CASE, """ n: number feminine: not used - for backward compatibility - gender: 'f' - masculine - 'm' - feminine - 'n' - neuter + 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 - ordinal: True - ordinal - False - cardinal """ # For backward compatibility if feminine: diff --git a/tests/test_ru.py b/tests/test_ru.py index 6cf85b3e..206873c4 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -35,7 +35,8 @@ def test_cardinal(self): self.assertEqual(num2words(2012, lang='ru'), "две тысячи двенадцать") self.assertEqual( num2words(12519.85, lang='ru'), - "двенадцать тысяч пятьсот девятнадцать целых восемьдесят пять сотых" + "двенадцать тысяч пятьсот девятнадцать целых восемьдесят пять " + "сотых" ) self.assertEqual( num2words(1234567890, lang='ru'), @@ -105,7 +106,7 @@ def test_cardinal_neuter(self): num2words(115, lang='ru', gender='n'), "сто пятнадцать" ) self.assertEqual( - num2words(122, lang='ru', gender='n'),"сто двадцать два" + num2words(122, lang='ru', gender='n'), "сто двадцать два" ) self.assertEqual( num2words(125.1, lang='ru', gender='n'), @@ -116,18 +117,21 @@ def test_cardinal_neuter(self): 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( From b0e9f6f0a1f228c3cc5b293e7968b3c0c6f035ad Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Wed, 3 May 2023 08:13:58 +0200 Subject: [PATCH 302/340] fix after conflicts resolved --- num2words/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/num2words/__init__.py b/num2words/__init__.py index 234b69ef..ee567f6f 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -24,6 +24,7 @@ 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_SL, lang_SR, lang_SV, lang_TE, lang_TG, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 87def57c4a747ee50009f79ad9fd6ca4a40fa138 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Mon, 1 May 2023 16:36:42 -0400 Subject: [PATCH 303/340] [it] Handle string inputs in `to_ordinal` Fixes #508. --- num2words/lang_IT.py | 12 ++++++------ tests/test_it.py | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index d532f7f4..427e6d36 100644 --- a/num2words/lang_IT.py +++ b/num2words/lang_IT.py @@ -146,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) @@ -167,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" diff --git a/tests/test_it.py b/tests/test_it.py index 9023355f..23c081d1 100644 --- a/tests/test_it.py +++ b/tests/test_it.py @@ -263,7 +263,7 @@ 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" ) @@ -271,6 +271,29 @@ def test_with_decimals(self): 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( From 9362dfc9bbe85607332c9173e9aff78bbe5e43c7 Mon Sep 17 00:00:00 2001 From: SkiBY Date: Wed, 21 Jun 2023 12:38:31 +0200 Subject: [PATCH 304/340] spellcheck --- num2words/lang_BY.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index 85d79c66..19be7b60 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -147,10 +147,10 @@ def setup(self): 'тры': 'трэці', 'чатыры': 'чацвёрты', 'пяць': 'пяты', - 'шесць': 'шосты', + 'шэсць': 'шосты', 'сем': 'сёмы', 'восем': 'восьмы', - 'девяць': 'дзявяты', + 'дзевяць': 'дзявяты', 'сто': 'соты', 'тысяча': 'тысячны', } @@ -162,10 +162,10 @@ def setup(self): 'тры': 'трох', 'чатыры': 'чатырох', 'пяць': 'пяці', - 'шесць': 'шасці', + 'шэсць': 'шасці', 'сем': 'сямі', 'восем': 'васьмі', - 'дзевяць': 'дзевяті', + 'дзевяць': 'дзевяцi', 'сто': 'ста', } From 30ca1f25ceb0ff45c643363ffb1be3af3e1c0252 Mon Sep 17 00:00:00 2001 From: SkiBY Date: Wed, 21 Jun 2023 15:36:36 +0200 Subject: [PATCH 305/340] coverage increased small gender fixes --- num2words/lang_BY.py | 11 ++++++----- tests/test_by.py | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index 19be7b60..84481d48 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -240,15 +240,16 @@ def to_ordinal(self, number, gender='m'): lastword = lastword[: lastword.rfind('д') + 1] + 'ны' if gender == 'f': - if lastword[-1:] in ['i', 'ы']: - lastword = lastword[:-2] + 'ая' + if lastword[-2:] in ['цi', ]: + lastword = lastword[:-2] + 'цяя' else: lastword = lastword[:-2] + 'ая' + if gender == 'n': - if lastword[-2:] == 'ий': - lastword = lastword[:-2] + 'ье' + if lastword[-2:] == ['цi', ]: + lastword = lastword[:-2] + 'цяе' else: - lastword = lastword[:-2] + 'ое' + lastword = lastword[:-2] + 'ае' outwords[-1] = self.title(lastword) if len(outwords) == 2 and 'адна' in outwords[-2]: diff --git a/tests/test_by.py b/tests/test_by.py index d4ea5920..d381d146 100644 --- a/tests/test_by.py +++ b/tests/test_by.py @@ -120,6 +120,10 @@ def test_to_ordinal(self): num2words(23, lang='by', to='ordinal'), 'дваццаць трэці' ) + self.assertEqual( + num2words(23, lang='by', to='ordinal', gender='f'), + 'дваццаць трэцяя' + ) self.assertEqual( num2words(40, lang='by', to='ordinal'), 'саракавы' @@ -144,10 +148,32 @@ def test_to_ordinal(self): num2words(500, lang='by', to='ordinal'), 'пяцісоты' ) + + self.assertEqual( + num2words(500, lang='by', to='ordinal', gender='f'), + 'пяцісотая' + ) + + self.assertEqual( + num2words(500, lang='by', to='ordinal', gender='n'), + 'пяцісотае' + ) + self.assertEqual( num2words(1000, lang='by', to='ordinal'), 'тысячны' ) + + self.assertEqual( + num2words(1000, lang='by', to='ordinal', gender='f'), + 'тысячная' + ) + + self.assertEqual( + num2words(1000, lang='by', to='ordinal', gender='n'), + 'тысячнае' + ) + self.assertEqual( num2words(1001, lang='by', to='ordinal'), 'тысяча першы' From 802e23e9a87364135ebac9d9fab3252c78acd309 Mon Sep 17 00:00:00 2001 From: SkiBY Date: Wed, 21 Jun 2023 19:46:26 +0200 Subject: [PATCH 306/340] coverage increased small gender fixes --- num2words/lang_BY.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index 84481d48..1deb5763 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -240,16 +240,16 @@ def to_ordinal(self, number, gender='m'): lastword = lastword[: lastword.rfind('д') + 1] + 'ны' if gender == 'f': - if lastword[-2:] in ['цi', ]: + if lastword[-2:] in ['ці', ]: lastword = lastword[:-2] + 'цяя' else: - lastword = lastword[:-2] + 'ая' + lastword = lastword[:-1] + 'ая' if gender == 'n': - if lastword[-2:] == ['цi', ]: + if lastword[-2:] == ['ці', ]: lastword = lastword[:-2] + 'цяе' else: - lastword = lastword[:-2] + 'ае' + lastword = lastword[:-1] + 'ае' outwords[-1] = self.title(lastword) if len(outwords) == 2 and 'адна' in outwords[-2]: From 5635a41c7111393a3a867076b4225cb436c80e2c Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 28 Jul 2023 10:59:40 +0600 Subject: [PATCH 307/340] Add gender and morphological cases support for Ukrainian Added two parameters: gender and case gender can accept either 'masculine' (default) or 'feminine' case can accept either 'nominative' (default) or 'genitive','dative','accusative','instrumetnal','locative' and 'vocative'. This parameters now working only for to='cardinal' --- num2words/lang_UK.py | 155 ++++++----- tests/test_uk.py | 609 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 698 insertions(+), 66 deletions(-) diff --git a/num2words/lang_UK.py b/num2words/lang_UK.py index a6c0a3bb..0b62d858 100644 --- a/num2words/lang_UK.py +++ b/num2words/lang_UK.py @@ -23,27 +23,27 @@ ZERO = ('нуль',) ONES_FEMININE = { - 1: ('одна',), - 2: ('дві',), - 3: ('три',), - 4: ('чотири',), - 5: ('п\'ять',), - 6: ('шість',), - 7: ('сім',), - 8: ('вісім',), - 9: ('дев\'ять',), + 1: ('одна', "однієї", "одній", "одну", "однією", "одній"), + 2: ('дві', "двох", "двом", "дві", "двома", "двох"), + 3: ('три', "трьох", "трьом", "три", "трьома", "трьох"), + 4: ('чотири', "чотирьох", "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', "шести", "шести", "шість", "шістьма", "шести"), + 7: ('сім', "семи", "семи", "сім", "сьома", "семи"), + 8: ('вісім', "восьми", "восьми", "вісім", "вісьма", "восьми"), + 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма","дев'яти"), } ONES = { - 1: ('один',), - 2: ('два',), - 3: ('три',), - 4: ('чотири',), - 5: ('п\'ять',), - 6: ('шість',), - 7: ('сім',), - 8: ('вісім',), - 9: ('дев\'ять',), + 1: ('один', 'одного', "одному", "один", "одним", "одному"), + 2: ('два', 'двох', "двом", "два", "двома", "двох"), + 3: ('три', 'трьох', "трьом", "три", "трьома", "трьох"), + 4: ('чотири', 'чотирьох', "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', 'шести', "шести", "шість", "шістьма", "шести"), + 7: ('сім', 'семи', "семи", "сім", "сьома", "семи"), + 8: ('вісім', 'восьми', "восьми", "вісім", "вісьма", "восьми"), + 9: ('дев\'ять', "дев'яти", "дев'яти", "дев'ять", "дев'ятьма","дев'яти"), } ONES_ORDINALS = { @@ -69,27 +69,27 @@ } TENS = { - 0: ('десять',), - 1: ('одинадцять',), - 2: ('дванадцять',), - 3: ('тринадцять',), - 4: ('чотирнадцять',), - 5: ('п\'ятнадцять',), - 6: ('шістнадцять',), - 7: ('сімнадцять',), - 8: ('вісімнадцять',), - 9: ('дев\'ятнадцять',), + 0: ('десять', 'десяти', "десяти", "десять", "десятьма", "десяти"), + 1: ('одинадцять', 'одинадцяти', "одинадцяти", "одинадцять", "одинадцятьма", "одинадцяти"), + 2: ('дванадцять', 'дванадцяти', "дванадцяти", "дванадцять", "дванадцятьма", "дванадцяти"), + 3: ('тринадцять', 'тринадцяти', "тринадцяти", "тринадцять", "тринадцятьма", "тринадцяти"), + 4: ('чотирнадцять', 'чотирнадцяти', "чотирнадцяти", "чотирнадцять", "чотирнадцятьма", "чотирнадцяти"), + 5: ("п'ятнадцять", "п'ятнадцяти", "п'ятнадцяти", "п'ятнадцять", "п'ятнадцятьма", "п'ятнадцяти"), + 6: ('шістнадцять', 'шістнадцяти', "шістнадцяти", "шістнадцять", "шістнадцятьма", "шістнадцяти"), + 7: ('сімнадцять', 'сімнадцяти', "сімнадцяти", "сімнадцять", "сімнадцятьма", "сімнадцяти"), + 8: ('вісімнадцять', 'вісімнадцяти', "вісімнадцяти", "вісімнадцять", "вісімнадцятьма", "вісімнадцяти"), + 9: ("дев'ятнадцять","дев'ятнадцяти","дев'ятнадцяти","дев'ятнадцять","дев'ятнадцятьма", "дев'ятнадцяти"), } TWENTIES = { - 2: ('двадцять',), - 3: ('тридцять',), - 4: ('сорок',), - 5: ('п\'ятдесят',), - 6: ('шістдесят',), - 7: ('сімдесят',), - 8: ('вісімдесят',), - 9: ('дев\'яносто',), + 2: ('двадцять', "двадцяти", "двадцяти", "двадцять", "двадцятьма", "двадцяти"), + 3: ('тридцять', "тридцяти", "тридцяти", "тридцять", "тридцятьма", "тридцяти"), + 4: ('сорок', "сорока", "сорока", "сорок", "сорока", "сорока"), + 5: ('п\'ятдесят', "п'ятдесяти", "п'ятдесяти", "п'ятдесят", "п'ятдесятьма", "п'ятдесяти"), + 6: ('шістдесят', "шістдесяти", "шістдесяти", "шістдесят", "шістдесятьма", "шістдесяти"), + 7: ('сімдесят', "сімдесяти", "сімдесяти", "сімдесят", "сімдесятьма", "сімдесяти"), + 8: ('вісімдесят', "вісімдесяти", "вісімдесяти", "вісімдесят", "вісімдесятьма","вісімдесяти"), + 9: ('дев\'яносто', "дев'яноста", "дев'яноста", "дев'яносто", "дев'яностами", "дев'яноста"), } TWENTIES_ORDINALS = { @@ -104,15 +104,15 @@ } HUNDREDS = { - 1: ('сто',), - 2: ('двісті',), - 3: ('триста',), - 4: ('чотириста',), - 5: ('п\'ятсот',), - 6: ('шістсот',), - 7: ('сімсот',), - 8: ('вісімсот',), - 9: ('дев\'ятсот',), + 1: ('сто', "ста", "ста", "сто", "стами", "стах"), + 2: ('двісті', "двохста", "двомстам", "двісті", "двомастами", "двохстах"), + 3: ('триста', "трьохста", "трьомстам", "триста", "трьомастами", "трьохстах"), + 4: ('чотириста',"чотирьохста", "чотирьомстам", "чотириста","чотирмастами", "чотирьохстах"), + 5: ('п\'ятсот', "п'ятиста", "п'ятистам", "п'ятсот", "п'ятьмастами", "п'ятистах"), + 6: ('шістсот', "шестиста", "шестистам", "шістсот", "шістьмастами", "шестистах"), + 7: ('сімсот', "семиста", "семистам", "сімсот", "сьомастами", "семистах"), + 8: ('вісімсот', "восьмиста", "восьмистам", "вісімсот", "восьмастами", "восьмистах"), + 9: ("дев'ятсот","дев'ятиста", "дев'ятистам", "дев'ятсот","дев'ятьмастами","дев'ятистах"), } HUNDREDS_ORDINALS = { @@ -128,16 +128,28 @@ } 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 + # Nominative Genitive Dative Accusative Instrumental Locative + # ----------------------------------------------------- --------------------------------------------------- --------------------------------------------------- --------------------------------------------------- ------------------------------------------------------- -------------------------------------------------------- + # 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 = { @@ -711,20 +723,31 @@ def setup(self): 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('.') leading_zero_count = len(right) - len(right.lstrip('0')) decimal_part = ((ZERO[0] + ' ') * leading_zero_count + - self._int2word(int(right))) + self._int2word(int(right), gender, morphological_case)) return u'%s %s %s' % ( - self._int2word(int(left)), + self._int2word(int(left), gender, morphological_case), self.pointword, 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: @@ -739,9 +762,9 @@ def pluralize(self, n, forms): return forms[form] - def _int2word(self, n, feminine=False): + def _int2word(self, n, feminine=False, morphological_case = 0): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n))]) + return ' '.join([self.negword, self._int2word(abs(n), feminine, morphological_case)]) if n == 0: return ZERO[0] @@ -758,20 +781,20 @@ def _int2word(self, n, feminine=False): 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])) + words.append(self.pluralize(x, THOUSANDS[i][morphological_case])) return ' '.join(words) diff --git a/tests/test_uk.py b/tests/test_uk.py index 84fb770a..3f57eb2d 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -117,6 +117,582 @@ "двісті двадцять тисяч двісті дев'яносто один") ) +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, "другий"), @@ -2449,10 +3025,43 @@ 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: + self.assertEqual(num2words(test[0], lang='uk', gender='feminine'), test[1]) + + def test_to_cardinal_nominative(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang='uk', case='nominative'), test[1]) + + def test_to_cardinal_genitive(self): + for test in TEST_CASES_CARDINAL_GENITIVE: + self.assertEqual(num2words(test[0], lang='uk', case='genitive'), test[1]) + + def test_to_cardinal_dative(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_DATIVE: + self.assertEqual(num2words(test[0], lang='uk', case='dative'), test[1]) + + def test_to_cardinal_accusative(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_ACCUSATIVE: + self.assertEqual(num2words(test[0], lang='uk', case='accusative'), test[1]) + + def test_to_cardinal_instrumental(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_INSTRUMENTAL: + self.assertEqual(num2words(test[0], lang='uk', case='instrumental'), test[1]) + + def test_to_cardinal_locative(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_LOCATIVE: + self.assertEqual(num2words(test[0], lang='uk', case='locative'), test[1]) + def test_to_ordinal(self): for test in TEST_CASES_ORDINAL: self.assertEqual( From 4b0b88ec9458a680f85d8c2b899ea5b000f9863a Mon Sep 17 00:00:00 2001 From: Salem Code Date: Sat, 12 Aug 2023 03:19:24 +0000 Subject: [PATCH 308/340] Add Saudi Riyal --- num2words/lang_EU.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index f2336701..d60fdcaf 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -46,7 +46,8 @@ class Num2Word_EU(Num2Word_Base): 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), 'ISK': (('króna', 'krónur'), ('aur', 'aurar')), - 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')) + 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')), + 'SAR': (('saudi riyal', 'saudi riyals'), ('halalah', 'halalas')) } From 2426f140491a6ede457f1950490c02c4038878ad Mon Sep 17 00:00:00 2001 From: Salem Code Date: Sat, 12 Aug 2023 03:20:38 +0000 Subject: [PATCH 309/340] Add SAR Adjective --- num2words/lang_EU.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index d60fdcaf..7c07bb56 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -64,7 +64,8 @@ class Num2Word_EU(Num2Word_Base): 'INR': 'Indian', 'HUF': 'Hungarian', 'ISK': 'íslenskar', - 'UZS': 'Uzbekistan' + 'UZS': 'Uzbekistan', + 'SAR': 'Saudi' } GIGA_SUFFIX = "illiard" From ad42ffdea573b448de8215e2a2316dcaace13d42 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sat, 12 Aug 2023 15:43:19 +0600 Subject: [PATCH 310/340] Reformat source code --- num2words/lang_UK.py | 318 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 255 insertions(+), 63 deletions(-) diff --git a/num2words/lang_UK.py b/num2words/lang_UK.py index 0b62d858..188d7ced 100644 --- a/num2words/lang_UK.py +++ b/num2words/lang_UK.py @@ -23,27 +23,27 @@ ZERO = ('нуль',) ONES_FEMININE = { - 1: ('одна', "однієї", "одній", "одну", "однією", "одній"), - 2: ('дві', "двох", "двом", "дві", "двома", "двох"), - 3: ('три', "трьох", "трьом", "три", "трьома", "трьох"), - 4: ('чотири', "чотирьох", "чотирьом", "чотири", "чотирма", "чотирьох"), - 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), - 6: ('шість', "шести", "шести", "шість", "шістьма", "шести"), - 7: ('сім', "семи", "семи", "сім", "сьома", "семи"), - 8: ('вісім', "восьми", "восьми", "вісім", "вісьма", "восьми"), - 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма","дев'яти"), + 1: ('одна', "однієї", "одній", "одну", "однією", "одній"), + 2: ('дві', "двох", "двом", "дві", "двома", "двох"), + 3: ('три', "трьох", "трьом", "три", "трьома", "трьох"), + 4: ('чотири', "чотирьох", "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', "шести", "шести", "шість", "шістьма", "шести"), + 7: ('сім', "семи", "семи", "сім", "сьома", "семи"), + 8: ('вісім', "восьми", "восьми", "вісім", "вісьма", "восьми"), + 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма", "дев'яти"), } ONES = { - 1: ('один', 'одного', "одному", "один", "одним", "одному"), - 2: ('два', 'двох', "двом", "два", "двома", "двох"), - 3: ('три', 'трьох', "трьом", "три", "трьома", "трьох"), - 4: ('чотири', 'чотирьох', "чотирьом", "чотири", "чотирма", "чотирьох"), - 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), - 6: ('шість', 'шести', "шести", "шість", "шістьма", "шести"), - 7: ('сім', 'семи', "семи", "сім", "сьома", "семи"), - 8: ('вісім', 'восьми', "восьми", "вісім", "вісьма", "восьми"), - 9: ('дев\'ять', "дев'яти", "дев'яти", "дев'ять", "дев'ятьма","дев'яти"), + 1: ('один', 'одного', "одному", "один", "одним", "одному"), + 2: ('два', 'двох', "двом", "два", "двома", "двох"), + 3: ('три', 'трьох', "трьом", "три", "трьома", "трьох"), + 4: ('чотири', 'чотирьох', "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', 'шести', "шести", "шість", "шістьма", "шести"), + 7: ('сім', 'семи', "семи", "сім", "сьома", "семи"), + 8: ('вісім', 'восьми', "восьми", "вісім", "вісьма", "восьми"), + 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма", "дев'яти"), } ONES_ORDINALS = { @@ -67,29 +67,118 @@ 18: ("вісімнадцятий", "вісімнадцяти"), 19: ("дев'ятнадцятий", "дев'ятнадцяти"), } - TENS = { - 0: ('десять', 'десяти', "десяти", "десять", "десятьма", "десяти"), - 1: ('одинадцять', 'одинадцяти', "одинадцяти", "одинадцять", "одинадцятьма", "одинадцяти"), - 2: ('дванадцять', 'дванадцяти', "дванадцяти", "дванадцять", "дванадцятьма", "дванадцяти"), - 3: ('тринадцять', 'тринадцяти', "тринадцяти", "тринадцять", "тринадцятьма", "тринадцяти"), - 4: ('чотирнадцять', 'чотирнадцяти', "чотирнадцяти", "чотирнадцять", "чотирнадцятьма", "чотирнадцяти"), - 5: ("п'ятнадцять", "п'ятнадцяти", "п'ятнадцяти", "п'ятнадцять", "п'ятнадцятьма", "п'ятнадцяти"), - 6: ('шістнадцять', 'шістнадцяти', "шістнадцяти", "шістнадцять", "шістнадцятьма", "шістнадцяти"), - 7: ('сімнадцять', 'сімнадцяти', "сімнадцяти", "сімнадцять", "сімнадцятьма", "сімнадцяти"), - 8: ('вісімнадцять', 'вісімнадцяти', "вісімнадцяти", "вісімнадцять", "вісімнадцятьма", "вісімнадцяти"), - 9: ("дев'ятнадцять","дев'ятнадцяти","дев'ятнадцяти","дев'ятнадцять","дев'ятнадцятьма", "дев'ятнадцяти"), + 0: ('десять', + 'десяти', + "десяти", + "десять", + "десятьма", + "десяти"), + 1: ('одинадцять', + 'одинадцяти', + "одинадцяти", + "одинадцять", + "одинадцятьма", + "одинадцяти"), + 2: ('дванадцять', + 'дванадцяти', + "дванадцяти", + "дванадцять", + "дванадцятьма", + "дванадцяти"), + 3: ('тринадцять', + 'тринадцяти', + "тринадцяти", + "тринадцять", + "тринадцятьма", + "тринадцяти"), + 4: ('чотирнадцять', + 'чотирнадцяти', + "чотирнадцяти", + "чотирнадцять", + "чотирнадцятьма", + "чотирнадцяти"), + 5: ("п'ятнадцять", + "п'ятнадцяти", + "п'ятнадцяти", + "п'ятнадцять", + "п'ятнадцятьма", + "п'ятнадцяти"), + 6: ('шістнадцять', + 'шістнадцяти', + "шістнадцяти", + "шістнадцять", + "шістнадцятьма", + "шістнадцяти"), + 7: ('сімнадцять', + 'сімнадцяти', + "сімнадцяти", + "сімнадцять", + "сімнадцятьма", + "сімнадцяти"), + 8: ('вісімнадцять', + 'вісімнадцяти', + "вісімнадцяти", + "вісімнадцять", + "вісімнадцятьма", + "вісімнадцяти"), + 9: ("дев'ятнадцять", + "дев'ятнадцяти", + "дев'ятнадцяти", + "дев'ятнадцять", + "дев'ятнадцятьма", + "дев'ятнадцяти"), } TWENTIES = { - 2: ('двадцять', "двадцяти", "двадцяти", "двадцять", "двадцятьма", "двадцяти"), - 3: ('тридцять', "тридцяти", "тридцяти", "тридцять", "тридцятьма", "тридцяти"), - 4: ('сорок', "сорока", "сорока", "сорок", "сорока", "сорока"), - 5: ('п\'ятдесят', "п'ятдесяти", "п'ятдесяти", "п'ятдесят", "п'ятдесятьма", "п'ятдесяти"), - 6: ('шістдесят', "шістдесяти", "шістдесяти", "шістдесят", "шістдесятьма", "шістдесяти"), - 7: ('сімдесят', "сімдесяти", "сімдесяти", "сімдесят", "сімдесятьма", "сімдесяти"), - 8: ('вісімдесят', "вісімдесяти", "вісімдесяти", "вісімдесят", "вісімдесятьма","вісімдесяти"), - 9: ('дев\'яносто', "дев'яноста", "дев'яноста", "дев'яносто", "дев'яностами", "дев'яноста"), + 2: ('двадцять', + "двадцяти", + "двадцяти", + "двадцять", + "двадцятьма", + "двадцяти"), + 3: ('тридцять', + "тридцяти", + "тридцяти", + "тридцять", + "тридцятьма", + "тридцяти"), + 4: ('сорок', + "сорока", + "сорока", + "сорок", + "сорока", + "сорока"), + 5: ('п\'ятдесят', + "п'ятдесяти", + "п'ятдесяти", + "п'ятдесят", + "п'ятдесятьма", + "п'ятдесяти"), + 6: ('шістдесят', + "шістдесяти", + "шістдесяти", + "шістдесят", + "шістдесятьма", + "шістдесяти"), + 7: ('сімдесят', + "сімдесяти", + "сімдесяти", + "сімдесят", + "сімдесятьма", + "сімдесяти"), + 8: ('вісімдесят', + "вісімдесяти", + "вісімдесяти", + "вісімдесят", + "вісімдесятьма", + "вісімдесяти"), + 9: ('дев\'яносто', + "дев'яноста", + "дев'яноста", + "дев'яносто", + "дев'яностами", + "дев'яноста"), } TWENTIES_ORDINALS = { @@ -104,15 +193,60 @@ } HUNDREDS = { - 1: ('сто', "ста", "ста", "сто", "стами", "стах"), - 2: ('двісті', "двохста", "двомстам", "двісті", "двомастами", "двохстах"), - 3: ('триста', "трьохста", "трьомстам", "триста", "трьомастами", "трьохстах"), - 4: ('чотириста',"чотирьохста", "чотирьомстам", "чотириста","чотирмастами", "чотирьохстах"), - 5: ('п\'ятсот', "п'ятиста", "п'ятистам", "п'ятсот", "п'ятьмастами", "п'ятистах"), - 6: ('шістсот', "шестиста", "шестистам", "шістсот", "шістьмастами", "шестистах"), - 7: ('сімсот', "семиста", "семистам", "сімсот", "сьомастами", "семистах"), - 8: ('вісімсот', "восьмиста", "восьмистам", "вісімсот", "восьмастами", "восьмистах"), - 9: ("дев'ятсот","дев'ятиста", "дев'ятистам", "дев'ятсот","дев'ятьмастами","дев'ятистах"), + 1: ('сто', + "ста", + "ста", + "сто", + "стами", + "стах"), + 2: ('двісті', + "двохста", + "двомстам", + "двісті", + "двомастами", + "двохстах"), + 3: ('триста', + "трьохста", + "трьомстам", + "триста", + "трьомастами", + "трьохстах"), + 4: ('чотириста', + "чотирьохста", + "чотирьомстам", + "чотириста", + "чотирмастами", + "чотирьохстах"), + 5: ('п\'ятсот', + "п'ятиста", + "п'ятистам", + "п'ятсот", + "п'ятьмастами", + "п'ятистах"), + 6: ('шістсот', + "шестиста", + "шестистам", + "шістсот", + "шістьмастами", + "шестистах"), + 7: ('сімсот', + "семиста", + "семистам", + "сімсот", + "сьомастами", + "семистах"), + 8: ('вісімсот', + "восьмиста", + "восьмистам", + "вісімсот", + "восьмастами", + "восьмистах"), + 9: ("дев'ятсот", + "дев'ятиста", + "дев'ятистам", + "дев'ятсот", + "дев'ятьмастами", + "дев'ятистах"), } HUNDREDS_ORDINALS = { @@ -128,28 +262,76 @@ } THOUSANDS = { - # Nominative Genitive Dative Accusative Instrumental Locative - # ----------------------------------------------------- --------------------------------------------------- --------------------------------------------------- --------------------------------------------------- ------------------------------------------------------- -------------------------------------------------------- # 10^3 - 1: (('тисяча', 'тисячі', 'тисяч'), ('тисячи', 'тисяч', 'тисяч'), ('тисячі', 'тисячам', 'тисячам'), ('тисячу', 'тисячі', 'тисяч'), ('тисячею', 'тисячами', 'тисячами'), ('тисячі', 'тисячах', 'тисячах'),), + 1: (('тисяча', 'тисячі', 'тисяч'), + ('тисячи', 'тисяч', 'тисяч'), + ('тисячі', 'тисячам', 'тисячам'), + ('тисячу', 'тисячі', 'тисяч'), + ('тисячею', 'тисячами', 'тисячами'), + ('тисячі', 'тисячах', 'тисячах'),), # 10^6 - 2: (('мільйон', 'мільйони', 'мільйонів'), ('мільйона', 'мільйонів', 'мільйонів'), ('мільйону', 'мільйонам', 'мільйонам'), ('мільйон', 'мільйони', 'мільйонів'), ('мільйоном', 'мільйонами', 'мільйонів'), ('мільйоні', 'мільйонах', 'мільйонах'),), + 2: (('мільйон', 'мільйони', 'мільйонів'), + ('мільйона', 'мільйонів', 'мільйонів'), + ('мільйону', 'мільйонам', 'мільйонам'), + ('мільйон', 'мільйони', 'мільйонів'), + ('мільйоном', 'мільйонами', 'мільйонів'), + ('мільйоні', 'мільйонах', 'мільйонах'),), # 10^9 - 3: (('мільярд', 'мільярди', 'мільярдів'), ('мільярда', 'мільярдів', 'мільярдів'), ('мільярду', 'мільярдам', 'мільярдам'), ('мільярд', 'мільярди', 'мільярдів'), ('мільярдом', 'мільярдами', 'мільярдів'), ('мільярді', 'мільярдах', 'мільярдах'),), + 3: (('мільярд', 'мільярди', 'мільярдів'), + ('мільярда', 'мільярдів', 'мільярдів'), + ('мільярду', 'мільярдам', 'мільярдам'), + ('мільярд', 'мільярди', 'мільярдів'), + ('мільярдом', 'мільярдами', 'мільярдів'), + ('мільярді', 'мільярдах', 'мільярдах'),), # 10^12 - 4: (('трильйон', 'трильйони', 'трильйонів'), ('трильйона', 'трильйонів', 'трильйонів'), ('трильйону', 'трильйонам', 'трильйонам'), ('трильйон', 'трильйони', 'трильйонів'), ('трильйоном', 'трильйонами', 'трильйонів'), ('трильйоні', 'трильйонах', 'трильйонах'),), + 4: (('трильйон', 'трильйони', 'трильйонів'), + ('трильйона', 'трильйонів', 'трильйонів'), + ('трильйону', 'трильйонам', 'трильйонам'), + ('трильйон', 'трильйони', 'трильйонів'), + ('трильйоном', 'трильйонами', 'трильйонів'), + ('трильйоні', 'трильйонах', 'трильйонах'),), # 10^15 - 5: (('квадрильйон', 'квадрильйони', 'квадрильйонів'), ('квадрильйона', 'квадрильйонів', 'квадрильйонів'), ('квадрильйону', 'квадрильйонам', 'квадрильйонам'), ('квадрильйон', 'квадрильйони', 'квадрильйонів'), ('квадрильйоном', 'квадрильйонами', 'квадрильйонів'), ('квадрильйоні', 'квадрильйонах', 'квадрильйонах'),), + 5: (('квадрильйон', 'квадрильйони', 'квадрильйонів'), + ('квадрильйона', 'квадрильйонів', 'квадрильйонів'), + ('квадрильйону', 'квадрильйонам', 'квадрильйонам'), + ('квадрильйон', 'квадрильйони', 'квадрильйонів'), + ('квадрильйоном', 'квадрильйонами', 'квадрильйонів'), + ('квадрильйоні', 'квадрильйонах', 'квадрильйонах'),), # 10^18 - 6: (('квінтильйон', 'квінтильйони', 'квінтильйонів'), ('квінтильйона', 'квінтильйонів', 'квінтильйонів'), ('квінтильйону', 'квінтильйонам', 'квінтильйонам'), ('квінтильйон', 'квінтильйони', 'квінтильйонів'), ('квінтильйоном', 'квінтильйонами', 'квінтильйонів'), ('квінтильйоні', 'квінтильйонах', 'квінтильйонах'),), + 6: (('квінтильйон', 'квінтильйони', 'квінтильйонів'), + ('квінтильйона', 'квінтильйонів', 'квінтильйонів'), + ('квінтильйону', 'квінтильйонам', 'квінтильйонам'), + ('квінтильйон', 'квінтильйони', 'квінтильйонів'), + ('квінтильйоном', 'квінтильйонами', 'квінтильйонів'), + ('квінтильйоні', 'квінтильйонах', 'квінтильйонах'),), # 10^21 - 7: (('секстильйон', 'секстильйони', 'секстильйонів'), ('секстильйона', 'секстильйонів', 'секстильйонів'), ('секстильйону', 'секстильйонам', 'секстильйонам'), ('секстильйон', 'секстильйони', 'секстильйонів'), ('секстильйоном', 'секстильйонами', 'секстильйонів'), ('секстильйоні', 'секстильйонах', 'секстильйонах'),), + 7: (('секстильйон', 'секстильйони', 'секстильйонів'), + ('секстильйона', 'секстильйонів', 'секстильйонів'), + ('секстильйону', 'секстильйонам', 'секстильйонам'), + ('секстильйон', 'секстильйони', 'секстильйонів'), + ('секстильйоном', 'секстильйонами', 'секстильйонів'), + ('секстильйоні', 'секстильйонах', 'секстильйонах'),), # 10^24 - 8: (('септильйон', 'септильйони', 'септильйонів'), ('септильйона', 'септильйонів', 'септильйонів'), ('септильйону', 'септильйонам', 'септильйонам'), ('септильйон', 'септильйони', 'септильйонів'), ('септильйоном', 'септильйонами', 'септильйонів'), ('септильйоні', 'септильйонах', 'септильйонах'),), + 8: (('септильйон', 'септильйони', 'септильйонів'), + ('септильйона', 'септильйонів', 'септильйонів'), + ('септильйону', 'септильйонам', 'септильйонам'), + ('септильйон', 'септильйони', 'септильйонів'), + ('септильйоном', 'септильйонами', 'септильйонів'), + ('септильйоні', 'септильйонах', 'септильйонах'),), # 10^27 - 9: (('октильйон', 'октильйони', 'октильйонів'), ('октильйона', 'октильйонів', 'октильйонів'), ('октильйону', 'октильйонам', 'октильйонам'), ('октильйон', 'октильйони', 'октильйонів'), ('октильйоном', 'октильйонами', 'октильйонів'), ('октильйоні', 'октильйонах', 'октильйонах'),), + 9: (('октильйон', 'октильйони', 'октильйонів'), + ('октильйона', 'октильйонів', 'октильйонів'), + ('октильйону', 'октильйонам', 'октильйонам'), + ('октильйон', 'октильйони', 'октильйонів'), + ('октильйоном', 'октильйонами', 'октильйонів'), + ('октильйоні', 'октильйонах', 'октильйонах'),), # 10^30 - 10: (('нонільйон', 'нонільйони', 'нонільйонів'), ('нонільйона', 'нонільйонів', 'нонільйонів'), ('нонільйону', 'нонільйонам', 'нонільйонам'), ('нонільйон', 'нонільйони', 'нонільйонів'), ('нонільйоном', 'нонільйонами', 'нонільйонів'), ('нонільйоні', 'нонільйонах', 'нонільйонах'),), + 10: (('нонільйон', 'нонільйони', 'нонільйонів'), + ('нонільйона', 'нонільйонів', 'нонільйонів'), + ('нонільйону', 'нонільйонам', 'нонільйонам'), + ('нонільйон', 'нонільйони', 'нонільйонів'), + ('нонільйоном', 'нонільйонами', 'нонільйонів'), + ('нонільйоні', 'нонільйонах', 'нонільйонах'),), } prefixes_ordinal = { @@ -726,7 +908,13 @@ def setup(self): def to_cardinal(self, number, **kwargs): if 'case' in kwargs: case = kwargs['case'] - morphological_case = ["nominative", "genitive", "dative", "accusative", "instrumental", "locative"].index(case) + morphological_case = [ + "nominative", + "genitive", + "dative", + "accusative", + "instrumental", + "locative"].index(case) else: morphological_case = 0 @@ -739,8 +927,9 @@ def to_cardinal(self, number, **kwargs): if '.' in n: left, right = n.split('.') 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 + - self._int2word(int(right), gender, morphological_case)) + right_side) return u'%s %s %s' % ( self._int2word(int(left), gender, morphological_case), self.pointword, @@ -762,9 +951,11 @@ def pluralize(self, n, forms): return forms[form] - def _int2word(self, n, feminine=False, morphological_case = 0): + def _int2word(self, n, feminine=False, morphological_case=0): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n), feminine, morphological_case)]) + n_value = self._int2word(abs(n), feminine, morphological_case) + return ' '.join([self.negword, + n_value]) if n == 0: return ZERO[0] @@ -794,7 +985,8 @@ def _int2word(self, n, feminine=False, morphological_case = 0): words.append(ones[n1][morphological_case]) if i > 0: - words.append(self.pluralize(x, THOUSANDS[i][morphological_case])) + thousands_val = THOUSANDS[i][morphological_case] + words.append(self.pluralize(x, thousands_val)) return ' '.join(words) From 585778fd6e49144d136f2ea55e48656a26b26013 Mon Sep 17 00:00:00 2001 From: SkiBY Date: Thu, 17 Aug 2023 19:00:52 +0200 Subject: [PATCH 311/340] flake8 converted and pass --- num2words/lang_BY.py | 373 ++++++++++++++++++++------------------- num2words/lang_RU.py | 3 +- tests/test_by.py | 403 +++++++++++++++++++++---------------------- tests/test_errors.py | 1 - 4 files changed, 396 insertions(+), 384 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index 1deb5763..c178149f 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -20,168 +20,173 @@ from .base import Num2Word_Base from .utils import get_digits, splitbyx -ZERO = 'нуль' +ZERO = "нуль" ONES_FEMININE = { - 1: 'адна', - 2: 'дзве', - 3: 'тры', - 4: 'чатыры', - 5: 'пяць', - 6: 'шэсць', - 7: 'сем', - 8: 'восем', - 9: 'дзевяць', + 1: "адна", + 2: "дзве", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", } ONES = { - 'f': { - 1: 'адна', - 2: 'дзве', - 3: 'тры', - 4: 'чатыры', - 5: 'пяць', - 6: 'шэсць', - 7: 'сем', - 8: 'восем', - 9: 'дзевяць', + "f": { + 1: "адна", + 2: "дзве", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", }, - 'm': { - 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: 'дзевяць', + "n": { + 1: "адно", + 2: "два", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", }, } TENS = { - 0: 'дзесяць', - 1: 'адзінаццаць', - 2: 'дванаццаць', - 3: 'трынаццаць', - 4: 'чатырнаццаць', - 5: 'пятнаццаць', - 6: 'шаснаццаць', - 7: 'сямнаццаць', - 8: 'васямнаццаць', - 9: 'дзевятнаццаць', + 0: "дзесяць", + 1: "адзінаццаць", + 2: "дванаццаць", + 3: "трынаццаць", + 4: "чатырнаццаць", + 5: "пятнаццаць", + 6: "шаснаццаць", + 7: "сямнаццаць", + 8: "васямнаццаць", + 9: "дзевятнаццаць", } TWENTIES = { - 2: 'дваццаць', - 3: 'трыццаць', - 4: 'сорак', - 5: 'пяцьдзясят', - 6: 'шэсцьдзясят', - 7: 'семдзесят', - 8: 'восемдзесят', - 9: 'дзевяноста', + 2: "дваццаць", + 3: "трыццаць", + 4: "сорак", + 5: "пяцьдзясят", + 6: "шэсцьдзясят", + 7: "семдзесят", + 8: "восемдзесят", + 9: "дзевяноста", } HUNDREDS = { - 1: 'сто', - 2: 'дзвесце', - 3: 'трыста', - 4: 'чатырыста', - 5: 'пяцьсот', - 6: 'шэсцьсот', - 7: 'семсот', - 8: 'восемсот', - 9: 'дзевяцьсот', + 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 + 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_BY(Num2Word_Base): CURRENCY_FORMS = { - 'RUB': ( - ('расійскі рубель', 'расійскія рублі', 'расійскіх рублёў'), - ('капейка', 'капейкі', 'капеек') + "RUB": ( + ("расійскі рубель", "расійскія рублі", "расійскіх рублёў"), + ("капейка", "капейкі", "капеек"), ), - 'EUR': (('еўра', 'еўра', 'еўра'), ('цэнт', 'цэнты', 'цэнтаў')), - 'USD': (('долар', 'долары', 'долараў'), ('цэнт', 'цэнты', 'цэнтаў')), - 'UAH': (('грыўна', 'грыўны', 'грыўнаў'), ('капейка', 'капейкі', 'капеек')), - 'KZT': (('тэнге', 'тэнге', 'тэнге'), ('тыйін', 'тыйіны', 'тыйінаў')), - 'BYN': ( - ('беларускі рубель', 'беларускія рублі', 'беларускіх рублёў'), - ('капейка', 'капейкі', 'капеек') + "EUR": (("еўра", "еўра", "еўра"), ("цэнт", "цэнты", "цэнтаў")), + "USD": (("долар", "долары", "долараў"), ("цэнт", "цэнты", "цэнтаў")), + "UAH": ( + ("грыўна", "грыўны", "грыўнаў"), + ("капейка", "капейкі", "капеек"), ), - 'UZS': (('сум', 'сумы', 'сумаў'), ('тыйін', 'тыйіны', 'тыйінаў')), + "KZT": (("тэнге", "тэнге", "тэнге"), ("тыйін", "тыйіны", "тыйінаў")), + "BYN": ( + ("беларускі рубель", "беларускія рублі", "беларускіх рублёў"), + ("капейка", "капейкі", "капеек"), + ), + "UZS": (("сум", "сумы", "сумаў"), ("тыйін", "тыйіны", "тыйінаў")), } def setup(self): - self.negword = 'мінус' - self.pointword = 'коска' + self.negword = "мінус" + self.pointword = "коска" self.ords = { - 'нуль': 'нулявы', - 'адзін': 'першы', - 'два': 'другі', - 'тры': 'трэці', - 'чатыры': 'чацвёрты', - 'пяць': 'пяты', - 'шэсць': 'шосты', - 'сем': 'сёмы', - 'восем': 'восьмы', - 'дзевяць': 'дзявяты', - 'сто': 'соты', - 'тысяча': 'тысячны', + "нуль": "нулявы", + "адзін": "першы", + "два": "другі", + "тры": "трэці", + "чатыры": "чацвёрты", + "пяць": "пяты", + "шэсць": "шосты", + "сем": "сёмы", + "восем": "восьмы", + "дзевяць": "дзявяты", + "сто": "соты", + "тысяча": "тысячны", } self.ords_adjective = { - 'адзін': 'адна', - 'адна': 'адна', - 'дзве': 'двух', - 'тры': 'трох', - 'чатыры': 'чатырох', - 'пяць': 'пяці', - 'шэсць': 'шасці', - 'сем': 'сямі', - 'восем': 'васьмі', - 'дзевяць': 'дзевяцi', - 'сто': 'ста', + "адзін": "адна", + "адна": "адна", + "дзве": "двух", + "тры": "трох", + "чатыры": "чатырох", + "пяць": "пяці", + "шэсць": "шасці", + "сем": "сямі", + "восем": "васьмі", + "дзевяць": "дзевяцi", + "сто": "ста", } - def to_cardinal(self, number, gender='m'): - n = str(number).replace(',', '.') - if '.' in n: - left, right = n.split('.') - if set(right) == {'0'}: + 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) + 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) @@ -197,91 +202,99 @@ def pluralize(self, n, forms): form = 2 return forms[form] - def to_ordinal(self, number, gender='m'): + def to_ordinal(self, number, gender="m"): self.verify_ordinal(number) - outwords = self.to_cardinal(number, gender).split(' ') + 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] + 'і' + 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] = '' + 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[-5:] == 'шэсць': - 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 + 'ны' - - if 'дву' in lastword[-2]: - lastword[-2].replace('дву', 'дзву') - - elif lastword[-1] == 'н' or lastword[-2] == 'н': - 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] + 'цяя' + lastword = ( + self.ords_adjective.get(lastword[:-3], lastword) + "соты" + ) + elif lastword[-5:] == "шэсць": + 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 + "ны" + + if "дву" in lastword[-2]: + lastword[-2].replace("дву", "дзву") + + elif lastword[-1] == "н" or lastword[-2] == "н": + 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] + 'ая' + lastword = lastword[:-1] + "ая" - if gender == 'n': - if lastword[-2:] == ['ці', ]: - lastword = lastword[:-2] + 'цяе' + if gender == "n": + if lastword[-2:] == [ + "ці", + ]: + lastword = lastword[:-2] + "цяе" else: - lastword = lastword[:-1] + 'ае' + lastword = lastword[:-1] + "ае" outwords[-1] = self.title(lastword) - if len(outwords) == 2 and 'адна' in outwords[-2]: + if len(outwords) == 2 and "адна" in outwords[-2]: outwords[-2] = outwords[-1] del outwords[-1] - if len(outwords) > 1 and 'тысяч' in outwords[-1]: + if len(outwords) > 1 and "тысяч" in outwords[-1]: outwords[-2] = outwords[-2] + outwords[-1] del outwords[-1] - return ' '.join(outwords).strip() + return " ".join(outwords).strip() def _money_verbose(self, number, currency): - gender = 'm' - if currency == 'UAH': - gender = 'f' + 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' + if currency in ("UAH", "RUB", "BYN"): + gender = "f" else: - gender = 'm' + gender = "m" return self._int2word(number, gender) - def _int2word(self, n, gender='m'): + def _int2word(self, n, gender="m"): if isinstance(gender, bool) and gender: - gender = 'f' + gender = "f" if n < 0: - return ' '.join([self.negword, self._int2word(abs(n), gender)]) + return " ".join([self.negword, self._int2word(abs(n), gender)]) if n == 0: return ZERO @@ -309,13 +322,13 @@ def _int2word(self, n, gender='m'): if i == 0: ones = ONES[gender] elif i == 1: - ones = ONES['f'] # Thousands are feminine + ones = ONES["f"] # Thousands are feminine else: - ones = ONES['m'] + ones = ONES["m"] words.append(ones[n1]) if i > 0: words.append(self.pluralize(x, THOUSANDS[i])) - return ' '.join(words) + return " ".join(words) diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 23578921..db9b38d0 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -121,7 +121,8 @@ class Num2Word_RU(Num2Word_Base): ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') ), 'PLN': ( - ('польский злотый', 'польских слотых', 'польских злотых'), ('грош', 'гроша', 'грошей') + ('польский злотый', 'польских слотых', 'польских злотых'), + ('грош', 'гроша', 'грошей') ), } diff --git a/tests/test_by.py b/tests/test_by.py index d381d146..fb50bf3a 100644 --- a/tests/test_by.py +++ b/tests/test_by.py @@ -24,325 +24,324 @@ class Num2WordsBYTest(TestCase): - def test_cardinal(self): - self.assertEqual(num2words(100, lang='by'), 'сто') - self.assertEqual(num2words(101, lang='by'), 'сто адзін') - self.assertEqual(num2words(110, lang='by'), 'сто дзесяць') - self.assertEqual(num2words(115, lang='by'), 'сто пятнаццаць') - self.assertEqual(num2words(123, lang='by'), 'сто дваццаць тры') - self.assertEqual(num2words(1000, lang='by'), 'адна тысяча') - self.assertEqual(num2words(1001, lang='by'), 'адна тысяча адзін') - self.assertEqual(num2words(2012, lang='by'), 'дзве тысячы дванаццаць') - self.assertEqual( - num2words(12519.85, lang='by'), - 'дванаццаць тысяч пяцьсот дзевятнаццаць коска восемдзесят пяць') - self.assertEqual( - num2words(1234567890, lang='by'), - 'адзін мільярд дзвесце трыццаць чатыры мільёны пяцьсот ' - 'шэсцьдзясят сем тысяч восемсот дзевяноста') - self.assertEqual( - num2words(461407892039002157189883901676, lang='by'), - 'чатырыста шэсцьдзясят адзін ' - 'актыльён чатырыста сем сэптыльёнаў восемсот дзевяноста ' - 'два секстыльёны трыццаць дзевяць квінтыльёнаў два квадрыльёны ' - 'сто пяцьдзясят сем трыльёнаў сто восемдзесят дзевяць мільярдаў ' - 'восемсот восемдзесят тры мільёны дзевяцьсот адна тысяча ' - 'шэсцьсот семдзесят шэсць') - self.assertEqual( - num2words(94234693663034822824384220291, lang='by'), - 'дзевяноста чатыры актыльёны ' - 'дзвесце трыццаць чатыры сэптыльёны шэсцьсот дзевяноста тры ' - 'секстыльёны шэсцьсот шэсцьдзясят тры квінтыльёны трыццаць ' - 'чатыры квадрыльёны восемсот дваццаць два трыльёны восемсот ' - 'дваццаць чатыры мільярды трыста восемдзесят чатыры мільёны ' - 'дзвесце дваццаць тысяч дзвесце дзевяноста адзін') - self.assertEqual(num2words(5, lang='by'), 'пяць') - self.assertEqual(num2words(15, lang='by'), 'пятнаццаць') - self.assertEqual(num2words(154, lang='by'), 'сто пяцьдзясят чатыры') - self.assertEqual( - num2words(1135, lang='by'), 'адна тысяча сто трыццаць пяць' - ) - self.assertEqual( - num2words(418531, lang='by'), - 'чатырыста васямнаццаць тысяч пяцьсот трыццаць адзін' - ) - self.assertEqual( - num2words(1000139, lang='by'), 'адзін мільён сто трыццаць дзевяць' - ) - self.assertEqual(num2words(-1, lang='by'), 'мінус адзін') - self.assertEqual(num2words(-15, lang='by'), 'мінус пятнаццаць') - self.assertEqual(num2words(-100, lang='by'), 'мінус сто') - - def test_floating_point(self): - self.assertEqual(num2words(5.2, lang='by'), 'пяць коска два') + self.assertEqual(num2words(100, lang="by"), "сто") + self.assertEqual(num2words(101, lang="by"), "сто адзін") + self.assertEqual(num2words(110, lang="by"), "сто дзесяць") + self.assertEqual(num2words(115, lang="by"), "сто пятнаццаць") + self.assertEqual(num2words(123, lang="by"), "сто дваццаць тры") + self.assertEqual(num2words(1000, lang="by"), "адна тысяча") + self.assertEqual(num2words(1001, lang="by"), "адна тысяча адзін") + self.assertEqual(num2words(2012, lang="by"), "дзве тысячы дванаццаць") self.assertEqual( - num2words(10.02, lang='by'), - 'дзесяць коска нуль два' + num2words(12519.85, lang="by"), + "дванаццаць тысяч пяцьсот дзевятнаццаць коска восемдзесят пяць", ) self.assertEqual( - num2words(15.007, lang='by'), - 'пятнаццаць коска нуль нуль сем' + num2words(1234567890, lang="by"), + "адзін мільярд дзвесце трыццаць чатыры мільёны пяцьсот " + "шэсцьдзясят сем тысяч восемсот дзевяноста", ) self.assertEqual( - num2words(561.42, lang='by'), - 'пяцьсот шэсцьдзясят адзін коска сорак два' + num2words(461407892039002157189883901676, lang="by"), + "чатырыста шэсцьдзясят адзін " + "актыльён чатырыста сем сэптыльёнаў восемсот дзевяноста " + "два секстыльёны трыццаць дзевяць квінтыльёнаў два квадрыльёны " + "сто пяцьдзясят сем трыльёнаў сто восемдзесят дзевяць мільярдаў " + "восемсот восемдзесят тры мільёны дзевяцьсот адна тысяча " + "шэсцьсот семдзесят шэсць", ) - self.assertEqual( - num2words(561.0, lang='by'), - 'пяцьсот шэсцьдзясят адзін коска нуль' + num2words(94234693663034822824384220291, lang="by"), + "дзевяноста чатыры актыльёны " + "дзвесце трыццаць чатыры сэптыльёны шэсцьсот дзевяноста тры " + "секстыльёны шэсцьсот шэсцьдзясят тры квінтыльёны трыццаць " + "чатыры квадрыльёны восемсот дваццаць два трыльёны восемсот " + "дваццаць чатыры мільярды трыста восемдзесят чатыры мільёны " + "дзвесце дваццаць тысяч дзвесце дзевяноста адзін", ) - - def test_to_ordinal(self): + self.assertEqual(num2words(5, lang="by"), "пяць") + self.assertEqual(num2words(15, lang="by"), "пятнаццаць") + self.assertEqual(num2words(154, lang="by"), "сто пяцьдзясят чатыры") self.assertEqual( - num2words(1, lang='by', to='ordinal'), - 'першы' + num2words(1135, lang="by"), "адна тысяча сто трыццаць пяць" ) self.assertEqual( - num2words(5, lang='by', to='ordinal'), - 'пяты' + num2words(418531, lang="by"), + "чатырыста васямнаццаць тысяч пяцьсот трыццаць адзін", ) self.assertEqual( - num2words(10, lang='by', to='ordinal'), - 'дзясяты' + num2words(1000139, lang="by"), "адзін мільён сто трыццаць дзевяць" ) + self.assertEqual(num2words(-1, lang="by"), "мінус адзін") + self.assertEqual(num2words(-15, lang="by"), "мінус пятнаццаць") + self.assertEqual(num2words(-100, lang="by"), "мінус сто") + def test_floating_point(self): + self.assertEqual(num2words(5.2, lang="by"), "пяць коска два") + self.assertEqual(num2words(10.02, lang="by"), "дзесяць коска нуль два") self.assertEqual( - num2words(13, lang='by', to='ordinal'), - 'трынаццаты' - ) - self.assertEqual( - num2words(20, lang='by', to='ordinal'), - 'дваццаты' - ) - self.assertEqual( - num2words(23, lang='by', to='ordinal'), - 'дваццаць трэці' - ) - self.assertEqual( - num2words(23, lang='by', to='ordinal', gender='f'), - 'дваццаць трэцяя' + num2words(15.007, lang="by"), "пятнаццаць коска нуль нуль сем" ) self.assertEqual( - num2words(40, lang='by', to='ordinal'), - 'саракавы' + num2words(561.42, lang="by"), + "пяцьсот шэсцьдзясят адзін коска сорак два", ) + self.assertEqual( - num2words(61, lang='by', to='ordinal'), - 'шэсцьдзясят першы' + num2words(561.0, lang="by"), "пяцьсот шэсцьдзясят адзін коска нуль" ) + + def test_to_ordinal(self): + self.assertEqual(num2words(1, lang="by", to="ordinal"), "першы") + self.assertEqual(num2words(5, lang="by", to="ordinal"), "пяты") + self.assertEqual(num2words(10, lang="by", to="ordinal"), "дзясяты") + + self.assertEqual(num2words(13, lang="by", to="ordinal"), "трынаццаты") + self.assertEqual(num2words(20, lang="by", to="ordinal"), "дваццаты") self.assertEqual( - num2words(70, lang='by', to='ordinal'), - 'сямідзясяты' + num2words(23, lang="by", to="ordinal"), "дваццаць трэці" ) self.assertEqual( - num2words(100, lang='by', to='ordinal'), - 'соты' + num2words(23, lang="by", to="ordinal", gender="f"), + "дваццаць трэцяя", ) + self.assertEqual(num2words(40, lang="by", to="ordinal"), "саракавы") self.assertEqual( - num2words(136, lang='by', to='ordinal'), - 'сто трыццаць шосты' + num2words(61, lang="by", to="ordinal"), "шэсцьдзясят першы" ) + self.assertEqual(num2words(70, lang="by", to="ordinal"), "сямідзясяты") + self.assertEqual(num2words(100, lang="by", to="ordinal"), "соты") self.assertEqual( - num2words(500, lang='by', to='ordinal'), - 'пяцісоты' + num2words(136, lang="by", to="ordinal"), "сто трыццаць шосты" ) + self.assertEqual(num2words(500, lang="by", to="ordinal"), "пяцісоты") self.assertEqual( - num2words(500, lang='by', to='ordinal', gender='f'), - 'пяцісотая' + num2words(500, lang="by", to="ordinal", gender="f"), "пяцісотая" ) self.assertEqual( - num2words(500, lang='by', to='ordinal', gender='n'), - 'пяцісотае' + num2words(500, lang="by", to="ordinal", gender="n"), "пяцісотае" ) - self.assertEqual( - num2words(1000, lang='by', to='ordinal'), - 'тысячны' - ) + self.assertEqual(num2words(1000, lang="by", to="ordinal"), "тысячны") self.assertEqual( - num2words(1000, lang='by', to='ordinal', gender='f'), - 'тысячная' + num2words(1000, lang="by", to="ordinal", gender="f"), "тысячная" ) self.assertEqual( - num2words(1000, lang='by', to='ordinal', gender='n'), - 'тысячнае' + num2words(1000, lang="by", to="ordinal", gender="n"), "тысячнае" ) self.assertEqual( - num2words(1001, lang='by', to='ordinal'), - 'тысяча першы' + num2words(1001, lang="by", to="ordinal"), "тысяча першы" ) self.assertEqual( - num2words(2000, lang='by', to='ordinal'), - 'двухтысячны' + num2words(2000, lang="by", to="ordinal"), "двухтысячны" ) self.assertEqual( - num2words(10000, lang='by', to='ordinal'), - 'дзесяцітысячны' + num2words(10000, lang="by", to="ordinal"), "дзесяцітысячны" ) self.assertEqual( - num2words(1000000, lang='by', to='ordinal'), - 'мільённы' + num2words(1000000, lang="by", to="ordinal"), "мільённы" ) self.assertEqual( - num2words(1000000000, lang='by', to='ordinal'), - 'мільярдны' + num2words(1000000000, lang="by", to="ordinal"), "мільярдны" ) def test_to_currency(self): self.assertEqual( - num2words(1.0, lang='by', to='currency', currency='EUR'), - 'адзін еўра, нуль цэнтаў' + num2words(1.0, lang="by", to="currency", currency="EUR"), + "адзін еўра, нуль цэнтаў", ) self.assertEqual( - num2words(1.0, lang='by', to='currency', currency='RUB'), - 'адзін расійскі рубель, нуль капеек' + num2words(1.0, lang="by", to="currency", currency="RUB"), + "адзін расійскі рубель, нуль капеек", ) self.assertEqual( - num2words(1.0, lang='by', to='currency', currency='BYN'), - 'адзін беларускі рубель, нуль капеек' + num2words(1.0, lang="by", to="currency", currency="BYN"), + "адзін беларускі рубель, нуль капеек", ) self.assertEqual( - num2words(1.0, lang='by', to='currency', currency='UAH'), - 'адна грыўна, нуль капеек' + num2words(1.0, lang="by", to="currency", currency="UAH"), + "адна грыўна, нуль капеек", ) self.assertEqual( - num2words(1234.56, lang='by', to='currency', currency='EUR'), - 'адна тысяча дзвесце трыццаць чатыры еўра, пяцьдзясят шэсць цэнтаў' + num2words(1234.56, lang="by", to="currency", currency="EUR"), + "адна тысяча дзвесце трыццаць чатыры еўра, " + "пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words(1234.56, lang='by', to='currency', currency='RUB'), - 'адна тысяча дзвесце трыццаць чатыры расійскія рублі, пяцьдзясят шэсць капеек' + num2words(1234.56, lang="by", to="currency", currency="RUB"), + "адна тысяча дзвесце трыццаць чатыры расійскія рублі, " + "пяцьдзясят шэсць капеек", ) self.assertEqual( - num2words(1234.56, lang='by', to='currency', currency='BYN'), - 'адна тысяча дзвесце трыццаць чатыры беларускія рублі, пяцьдзясят шэсць капеек' + num2words(1234.56, lang="by", to="currency", currency="BYN"), + "адна тысяча дзвесце трыццаць чатыры беларускія рублі, " + "пяцьдзясят шэсць капеек", ) self.assertEqual( - num2words(1234.56, lang='by', to='currency', currency='UAH'), - 'адна тысяча дзвесце трыццаць чатыры грыўны, пяцьдзясят шэсць капеек' + num2words(1234.56, lang="by", to="currency", currency="UAH"), + "адна тысяча дзвесце трыццаць чатыры грыўны, " + "пяцьдзясят шэсць капеек", ) self.assertEqual( - num2words(10111, lang='by', to='currency', currency='EUR', - separator=' і'), - 'сто адзін еўра і адзінаццаць цэнтаў' + num2words( + 10111, lang="by", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і адзінаццаць цэнтаў", ) self.assertEqual( - num2words(10111, lang='by', to='currency', currency='RUB', - separator=' і'), - 'сто адзін расійскі рубель і адзінаццаць капеек' + num2words( + 10111, lang="by", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і адзінаццаць капеек", ) self.assertEqual( - num2words(10111, lang='by', to='currency', currency='BYN', - separator=' і'), - 'сто адзін беларускі рубель і адзінаццаць капеек' + num2words( + 10111, lang="by", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і адзінаццаць капеек", ) self.assertEqual( - num2words(10111, lang='by', to='currency', currency='UAH', - separator=' і'), - 'сто адна грыўна і адзінаццаць капеек' + num2words( + 10111, lang="by", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і адзінаццаць капеек", ) self.assertEqual( - num2words(10121, lang='by', to='currency', currency='EUR', - separator=' і'), - 'сто адзін еўра і дваццаць адзін цэнт' + num2words( + 10121, lang="by", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і дваццаць адзін цэнт", ) self.assertEqual( - num2words(10121, lang='by', to='currency', currency='RUB', - separator=' і'), - 'сто адзін расійскі рубель і дваццаць адна капейка' + num2words( + 10121, lang="by", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і дваццаць адна капейка", ) self.assertEqual( - num2words(10121, lang='by', to='currency', currency='BYN', - separator=' і'), - 'сто адзін беларускі рубель і дваццаць адна капейка' + num2words( + 10121, lang="by", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і дваццаць адна капейка", ) self.assertEqual( - num2words(10121, lang='by', to='currency', currency='UAH', - separator=' і'), - 'сто адна грыўна і дваццаць адна капейка' + num2words( + 10121, lang="by", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і дваццаць адна капейка", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='EUR', - separator=' і'), - 'сто адзін еўра і дваццаць два цэнты' + num2words( + 10122, lang="by", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і дваццаць два цэнты", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='RUB', - separator=' і'), - 'сто адзін расійскі рубель і дваццаць дзве капейкі' + num2words( + 10122, lang="by", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і дваццаць дзве капейкі", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='BYN', - separator=' і'), - 'сто адзін беларускі рубель і дваццаць дзве капейкі' + num2words( + 10122, lang="by", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і дваццаць дзве капейкі", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='UAH', - separator=' і'), - 'сто адна грыўна і дваццаць дзве капейкі' + num2words( + 10122, lang="by", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і дваццаць дзве капейкі", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='KZT', - separator=' і'), - 'сто адзін тэнге і дваццаць два тыйіны' + num2words( + 10122, lang="by", to="currency", currency="KZT", separator=" і" + ), + "сто адзін тэнге і дваццаць два тыйіны", ) self.assertEqual( - num2words(-1251985, lang='by', to='currency', currency='EUR', - cents=False), - 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць еўра, 85 цэнтаў' + num2words( + -1251985, lang="by", to="currency", currency="EUR", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць еўра, 85 цэнтаў", ) self.assertEqual( - num2words(-1251985, lang='by', to='currency', currency='RUB', - cents=False), - 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць расійскіх рублёў, 85 капеек' + num2words( + -1251985, lang="by", to="currency", currency="RUB", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " + "расійскіх рублёў, 85 капеек", ) self.assertEqual( - num2words(-1251985, lang='by', to='currency', currency='BYN', - cents=False), - 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць беларускіх рублёў, 85 капеек' + num2words( + -1251985, lang="by", to="currency", currency="BYN", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " + "беларускіх рублёў, 85 капеек", ) self.assertEqual( - num2words(-1251985, lang='by', to='currency', currency='UAH', - cents=False), - 'мінус дванаццаць тысяч пяцьсот дзевятнаццаць грыўнаў, 85 капеек' + num2words( + -1251985, lang="by", to="currency", currency="UAH", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць грыўнаў, 85 капеек", ) self.assertEqual( - num2words('38.4', lang='by', to='currency', separator=' і', - cents=False, currency='EUR'), - 'трыццаць восем еўра і 40 цэнтаў' + num2words( + "38.4", + lang="by", + to="currency", + separator=" і", + cents=False, + currency="EUR", + ), + "трыццаць восем еўра і 40 цэнтаў", ) self.assertEqual( - num2words('38.4', lang='by', to='currency', separator=' і', - cents=False, currency='RUB'), - 'трыццаць восем расійскіх рублёў і 40 капеек' + num2words( + "38.4", + lang="by", + to="currency", + separator=" і", + cents=False, + currency="RUB", + ), + "трыццаць восем расійскіх рублёў і 40 капеек", ) self.assertEqual( - num2words('38.4', lang='by', to='currency', separator=' і', - cents=False, currency='UAH'), - 'трыццаць восем грыўнаў і 40 капеек' + num2words( + "38.4", + lang="by", + to="currency", + separator=" і", + cents=False, + currency="UAH", + ), + "трыццаць восем грыўнаў і 40 капеек", ) self.assertEqual( - num2words('1230.56', lang='by', to='currency', currency='USD'), - 'адна тысяча дзвесце трыццаць долараў, пяцьдзясят шэсць цэнтаў' + num2words("1230.56", lang="by", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць долараў, пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words('1231.56', lang='by', to='currency', currency='USD'), - 'адна тысяча дзвесце трыццаць адзін долар, пяцьдзясят шэсць цэнтаў' + num2words("1231.56", lang="by", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць адзін долар, " + "пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words('1234.56', lang='by', to='currency', currency='USD'), - 'адна тысяча дзвесце трыццаць чатыры долары, пяцьдзясят шэсць ' - 'цэнтаў' + num2words("1234.56", lang="by", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць чатыры долары, пяцьдзясят шэсць " + "цэнтаў", ) self.assertEqual( - num2words(10122, lang='by', to='currency', currency='UZS', - separator=' і'), - 'сто адзін сум і дваццаць два тыйіны' + num2words( + 10122, lang="by", to="currency", currency="UZS", separator=" і" + ), + "сто адзін сум і дваццаць два тыйіны", ) diff --git a/tests/test_errors.py b/tests/test_errors.py index 096b99c3..a25553f5 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -28,7 +28,6 @@ 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') From d1229aa4f289deaeecccddb31c4370fe4e1522ef Mon Sep 17 00:00:00 2001 From: SkiBY Date: Fri, 18 Aug 2023 18:10:22 +0200 Subject: [PATCH 312/340] increase of coverage --- num2words/lang_BY.py | 16 ++++++++++------ tests/test_by.py | 8 ++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index c178149f..f0ace74e 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -240,8 +240,6 @@ def to_ordinal(self, number, gender="m"): if lastword[-1] == "ч": lastword = lastword + "ны" - if "дву" in lastword[-2]: - lastword[-2].replace("дву", "дзву") elif lastword[-1] == "н" or lastword[-2] == "н": lastword = lastword[: lastword.rfind("н") + 1] + "ны" @@ -257,8 +255,8 @@ def to_ordinal(self, number, gender="m"): lastword = lastword[:-1] + "ая" if gender == "n": - if lastword[-2:] == [ - "ці", + if lastword[-2:] in [ + "ці", "ца" ]: lastword = lastword[:-2] + "цяе" else: @@ -269,10 +267,16 @@ def to_ordinal(self, number, gender="m"): outwords[-2] = outwords[-1] del outwords[-1] - if len(outwords) > 1 and "тысяч" in outwords[-1]: - outwords[-2] = outwords[-2] + outwords[-1] + if len(outwords) > 2 and "тысяч" in outwords[-1]: + if 'сорак' in outwords[-3]: + outwords[-3] = outwords[-3].replace('сорак', 'сарака') + outwords[-3] = outwords[-3] + outwords[-2] + outwords[-1] + del outwords[-1] del outwords[-1] + elif len(outwords) > 1 and "тысяч" in outwords[-1]: + outwords[-2] = outwords[-2] + outwords[-1] + del outwords[-1] return " ".join(outwords).strip() def _money_verbose(self, number, currency): diff --git a/tests/test_by.py b/tests/test_by.py index fb50bf3a..087c0c11 100644 --- a/tests/test_by.py +++ b/tests/test_by.py @@ -95,6 +95,7 @@ def test_floating_point(self): def test_to_ordinal(self): self.assertEqual(num2words(1, lang="by", to="ordinal"), "першы") self.assertEqual(num2words(5, lang="by", to="ordinal"), "пяты") + self.assertEqual(num2words(6, lang="by", to="ordinal"), "шосты") self.assertEqual(num2words(10, lang="by", to="ordinal"), "дзясяты") self.assertEqual(num2words(13, lang="by", to="ordinal"), "трынаццаты") @@ -106,6 +107,10 @@ def test_to_ordinal(self): num2words(23, lang="by", to="ordinal", gender="f"), "дваццаць трэцяя", ) + self.assertEqual( + num2words(23, lang="by", to="ordinal", gender="n"), + "дваццаць трэцяе", + ) self.assertEqual(num2words(40, lang="by", to="ordinal"), "саракавы") self.assertEqual( num2words(61, lang="by", to="ordinal"), "шэсцьдзясят першы" @@ -144,6 +149,9 @@ def test_to_ordinal(self): self.assertEqual( num2words(10000, lang="by", to="ordinal"), "дзесяцітысячны" ) + self.assertEqual( + num2words(42000, lang="by", to="ordinal"), "саракадвухтысячны" + ) self.assertEqual( num2words(1000000, lang="by", to="ordinal"), "мільённы" ) From 6c8e66bd37f38eac3ef339963b88ebf8140b26d7 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Sat, 19 Aug 2023 00:31:33 +0600 Subject: [PATCH 313/340] Fix style in tests --- tests/test_uk.py | 51 ++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/tests/test_uk.py b/tests/test_uk.py index 3f57eb2d..4dcd7cb1 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -280,7 +280,8 @@ (1001, "однієї тисячи одного"), (2012, "двох тисяч дванадцяти"), (12519, "дванадцяти тисяч п'ятиста дев'ятнадцяти"), - (12519.85, "дванадцяти тисяч п'ятиста дев'ятнадцяти кома вісімдесяти п'яти"), + (12519.85, "дванадцяти тисяч п'ятиста дев'ятнадцяти " + "кома вісімдесяти п'яти"), (-260000, "мінус двохста шістдесяти тисяч"), (1000000, "одного мільйона"), (1000000000, "одного мільярда"), @@ -376,7 +377,8 @@ (1001, "одній тисячі одному"), (2012, "двом тисячам дванадцяти"), (12519, "дванадцяти тисячам п'ятистам дев'ятнадцяти"), - (12519.85, "дванадцяти тисячам п'ятистам дев'ятнадцяти кома вісімдесяти п'яти"), + (12519.85, "дванадцяти тисячам п'ятистам дев'ятнадцяти " + "кома вісімдесяти п'яти"), (-260000, "мінус двомстам шістдесяти тисячам"), (1000000, "одному мільйону"), (1000000000, "одному мільярду"), @@ -568,12 +570,14 @@ (1001, "однією тисячею одним"), (2012, "двома тисячами дванадцятьма"), (12519, "дванадцятьма тисячами п'ятьмастами дев'ятнадцятьма"), - (12519.85, "дванадцятьма тисячами п'ятьмастами дев'ятнадцятьма кома вісімдесятьма п'ятьма"), + (12519.85, "дванадцятьма тисячами п'ятьмастами дев'ятнадцятьма " + "кома вісімдесятьма п'ятьма"), (-260000, "мінус двомастами шістдесятьма тисячами"), (1000000, "одним мільйоном"), (1000000000, "одним мільярдом"), (1234567890, "одним мільярдом двомастами тридцятьма чотирма мільйонами " - "п'ятьмастами шістдесятьма сьома тисячами восьмастами дев'яностами"), + "п'ятьмастами шістдесятьма сьома тисячами восьмастами " + "дев'яностами"), (1000000000000, "одним трильйоном"), (1000000000000000, "одним квадрильйоном"), (1000000000000000000, "одним квінтильйоном"), @@ -589,12 +593,13 @@ "дев'ятьма мільярдів восьмастами вісімдесятьма трьома мільйонами " "дев'ятьмастами однією тисячею шістьмастами сімдесятьма шістьма"), (719094234693663034822824384220291, - "сьомастами дев'ятнадцятьма нонільйонів дев'яностами чотирма октильйонами " - "двомастами тридцятьма чотирма септильйонами шістьмастами дев'яностами трьома " - "секстильйонами шістьмастами шістдесятьма трьома квінтильйонами тридцятьма " - "чотирма квадрильйонами восьмастами двадцятьма двома трильйонами восьмастами " - "двадцятьма чотирма мільярдами трьомастами вісімдесятьма чотирма мільйонами " - "двомастами двадцятьма тисячами двомастами дев'яностами одним") + "сьомастами дев'ятнадцятьма нонільйонів дев'яностами чотирма " + "октильйонами двомастами тридцятьма чотирма септильйонами шістьмастами " + "дев'яностами трьома секстильйонами шістьмастами шістдесятьма трьома " + "квінтильйонами тридцятьма чотирма квадрильйонами восьмастами двадцятьма " + "двома трильйонами восьмастами двадцятьма чотирма мільярдами трьомастами " + "вісімдесятьма чотирма мільйонами двомастами двадцятьма тисячами " + "двомастами дев'яностами одним") ) TEST_CASES_CARDINAL_LOCATIVE = ( @@ -664,7 +669,8 @@ (1001, "одній тисячі одному"), (2012, "двох тисячах дванадцяти"), (12519, "дванадцяти тисячах п'ятистах дев'ятнадцяти"), - (12519.85, "дванадцяти тисячах п'ятистах дев'ятнадцяти кома вісімдесяти п'яти"), + (12519.85, "дванадцяти тисячах п'ятистах дев'ятнадцяти " + "кома вісімдесяти п'яти"), (-260000, "мінус двохстах шістдесяти тисячах"), (1000000, "одному мільйоні"), (1000000000, "одному мільярді"), @@ -3025,42 +3031,49 @@ 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: - self.assertEqual(num2words(test[0], lang='uk', gender='feminine'), test[1]) + 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: - self.assertEqual(num2words(test[0], lang='uk', case='nominative'), test[1]) + 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: - self.assertEqual(num2words(test[0], lang='uk', case='genitive'), test[1]) + 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: - self.assertEqual(num2words(test[0], lang='uk', case='dative'), test[1]) + 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: - self.assertEqual(num2words(test[0], lang='uk', case='accusative'), test[1]) + 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: - self.assertEqual(num2words(test[0], lang='uk', case='instrumental'), test[1]) + word = num2words(test[0], lang='uk', case='instrumental') + self.assertEqual(word, test[1]) def test_to_cardinal_locative(self): self.maxDiff = None for test in TEST_CASES_CARDINAL_LOCATIVE: - self.assertEqual(num2words(test[0], lang='uk', case='locative'), test[1]) + word = num2words(test[0], lang='uk', case='locative') + self.assertEqual(word, test[1]) def test_to_ordinal(self): for test in TEST_CASES_ORDINAL: From 2da1f924dfd49c57a9fa841bd39a6583564badbd Mon Sep 17 00:00:00 2001 From: Michal Juranyi Date: Sun, 3 Sep 2023 20:39:47 +0200 Subject: [PATCH 314/340] Add Slovak language support Signed-off-by: Michal Juranyi --- num2words/__init__.py | 5 +- num2words/lang_SK.py | 160 ++++++++++++++++++++++++++++++++++++++++++ tests/test_sk.py | 98 ++++++++++++++++++++++++++ 3 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 num2words/lang_SK.py create mode 100644 tests/test_sk.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 0942928f..53a28591 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -23,8 +23,8 @@ 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_SL, lang_SR, lang_SV, lang_TE, lang_TG, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_RO, lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE, + lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), @@ -57,6 +57,7 @@ '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(), 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/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" + ) From 125140690caff1277e1d2f760f171e88c748e102 Mon Sep 17 00:00:00 2001 From: SkiBY Date: Mon, 16 Oct 2023 22:38:17 +0200 Subject: [PATCH 315/340] [FIX]isort and flake returned [FIX]isort and flake returned --- num2words/lang_BY.py | 1 - tox.ini | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/num2words/lang_BY.py b/num2words/lang_BY.py index f0ace74e..ec825fd0 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BY.py @@ -240,7 +240,6 @@ def to_ordinal(self, number, gender="m"): if lastword[-1] == "ч": lastword = lastword + "ны" - elif lastword[-1] == "н" or lastword[-2] == "н": lastword = lastword[: lastword.rfind("н") + 1] + "ны" elif lastword[-1] == "д" or lastword[-2] == "д": diff --git a/tox.ini b/tox.ini index 71beb41b..8e334bcf 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ python = 3.7: py37 3.8: py38 3.9: py39 - 3.10: py310 + 3.10: isort, flake8, py310 3.11: py311 From 54b9701d536e1bf76005df575e39a0a74086168f Mon Sep 17 00:00:00 2001 From: SkiBY Date: Tue, 17 Oct 2023 10:39:22 +0200 Subject: [PATCH 316/340] touch --- tests/test_errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_errors.py b/tests/test_errors.py index a25553f5..3b53c80a 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -30,4 +30,4 @@ def test_NotImplementedError(self): def test_types_NotImplementedError(self): with self.assertRaises(NotImplementedError): - num2words(100, lang="en", to='babidibibidiboo') + num2words(100, lang="en", to='babidibibidiboo!') From aa81e80f0d6f7e0f3fc29a8876bdb1d5162ee822 Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia Date: Wed, 18 Oct 2023 10:46:15 -0400 Subject: [PATCH 317/340] Added changes for release 0.5.13 --- CHANGES.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 4a1d1e1d..ea33f3e2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,30 @@ 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 ---------------------------- From 97668c0843d2a2abd1132d2d504cf9a1d5d079b8 Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Sun, 5 Nov 2023 13:51:44 +0100 Subject: [PATCH 318/340] added Welsh (cy) and Chechen (ce) --- num2words/__init__.py | 5 +- num2words/lang_CE.py | 509 ++++++++++++++++++++++++++++++++++++++ num2words/lang_CY.py | 556 ++++++++++++++++++++++++++++++++++++++++++ tests/test_ce.py | 344 ++++++++++++++++++++++++++ tests/test_cy.py | 430 ++++++++++++++++++++++++++++++++ 5 files changed, 1843 insertions(+), 1 deletion(-) create mode 100644 num2words/lang_CE.py create mode 100644 num2words/lang_CY.py create mode 100644 tests/test_ce.py create mode 100644 tests/test_cy.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 789af300..5641598e 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,7 +17,8 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BY, lang_CZ, lang_DE, lang_DK, +from . import (lang_AM, lang_AR, lang_AZ, lang_BY, + 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_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, @@ -31,6 +32,8 @@ 'ar': lang_AR.Num2Word_AR(), 'az': lang_AZ.Num2Word_AZ(), 'by': lang_BY.Num2Word_BY(), + '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(), diff --git a/num2words/lang_CE.py b/num2words/lang_CE.py new file mode 100644 index 00000000..0d6c01ef --- /dev/null +++ b/num2words/lang_CE.py @@ -0,0 +1,509 @@ +# -*- 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 .lang_EU import Num2Word_EU +from .currency import parse_currency_parts, prefix_currency + +# 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 ! + +class Num2Word_CE(Num2Word_EU): + CURRENCY_FORMS = { + # currency code: (sg, pl), (sg, pl) + + 'EUR': (('Евро', 'Евро'), ("Сент", "Сенташ")), + 'RUB': (("Сом", "Сомаш"), ("Кепек", "Кепекаш")), + 'USD': (("Доллар", "Доллараш"), ("Сент", "Сенташ")), + 'GBP': (("Фунт", "Фунташ"), ("Пенни", "Пенни")) + } + + def setup(self): + Num2Word_EU.setup(self) + + def __init__(self): + pass + + 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: + #if case in CARDINALS[number]: + # return CARDINALS[number][case] + #else: + # add casesuffix to ABS stem + return self.makecase(number, case, clazz) + #if CARDINALS[number]["abs"][-1] in "а": + # return CARDINALS[number]["abs"] + CARDINALS["casesuffix_voc"][case] + #else: + # return CARDINALS[number]["abs"] + CARDINALS["casesuffix_cons"][case] + 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="attr") + + 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] + #if case != "abs": + # if devise[-1] in "аеиоуяю": + # devise += CARDINALS["casesuffix_voc"][case] + # else: + # devise += CARDINALS["casesuffix_cons"][case] + # if centime[-1] in "аеиоуяю": + # centime += CARDINALS["casesuffix_voc"][case] + # else: + # centime += CARDINALS["casesuffix_cons"][case] + 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, case) + cents_str = self._cents_verbose(right, currency, case) \ + if cents else self._cents_terse(right, currency) + + + + + return u'%s%s %s%s %s %s' % ( + minus_str, + money_str, + devise, # always singular + separator, + cents_str, + centime + ) + + + 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..6d6f3b1e --- /dev/null +++ b/num2words/lang_CY.py @@ -0,0 +1,556 @@ +# -*- 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 .lang_EU import Num2Word_EU +from .currency import parse_currency_parts, prefix_currency + +# 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, ordinal=False): + 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 + result = [] # list group of number words and mutation info (for the following word) + 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 + elif 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) + #print("BBBB", number, tens, degau) #, softmutation(degau)) + + 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 = [] # groups of three digits starting from right (units (1 - 999), thousands, millions, .. + 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 u'%s%s' % ( + minus_str, + money_str, + #self.pluralize(right, cr2) + ) + elif left == 0: + # no pence + return u'%s%s' % ( + minus_str, + cents_str, + #self.pluralize(right, cr2) + ) + + return u'%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 currenceis + if currency in CURRENCIES_FEM: + 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) + 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 + #print("eeeeeeeee", m) + #m.append((c, None)) + #print("fffffffff", m) + 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", number, word) + if mutation == "SM": + return softmutation(word) + elif mutation == "AM": + return aspiratedmutation(word) + return word + +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] == "h": + return 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 + +#def omitt_if_zero(number_to_string): +# return "" if number_to_string == ZERO else number_to_string diff --git a/tests/test_ce.py b/tests/test_ce.py new file mode 100644 index 00000000..f4f71ae1 --- /dev/null +++ b/tests/test_ce.py @@ -0,0 +1,344 @@ +# -*- 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_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, "пхи квинтиллиард ялх бӀе квинтиллион пхи бӀе кхузткъе квадриллиард"), + ] + +TEST_CURRENCY = [ + (143.55, "abs", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), + ] + +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]) + + def test_currency(self): + for test in TEST_CURRENCY: + self.assertEqual(num2words(test[0], lang='ce', to="currency", currency="RUB", case=test[1]), test[2]) + + def test_decimals(self): + for test in TEST_CASES_DECIMALS: + self.assertEqual(num2words(test[0], lang='ce'), test[1]) + + diff --git a/tests/test_cy.py b/tests/test_cy.py new file mode 100644 index 00000000..7242df52 --- /dev/null +++ b/tests/test_cy.py @@ -0,0 +1,430 @@ +# -*- 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"), + (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_DECIMALS = [ + (123.4567, "cant a thri ar hugain pwynt pedwar pump chwech saith") + ] + +TEST_CASES_TO_CURRENCY_GBP = ( + (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"), + (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_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_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_counted(self): + for test in TEST_CASES_COUNTED: + self.assertEqual(num2words(test[0], lang='cy', counted=test[1], gender=test[2]), test[3]) + + + From 087e402f557f8c4f3b952de9b084668fc548b3e9 Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Sun, 5 Nov 2023 13:52:02 +0100 Subject: [PATCH 319/340] mini doc for new languages --- num2words/README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 num2words/README.md diff --git a/num2words/README.md b/num2words/README.md new file mode 100644 index 00000000..18558096 --- /dev/null +++ b/num2words/README.md @@ -0,0 +1,54 @@ +# 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 + From 7d9de8a34cb352bb8c88fcc606f99d9ee6885b04 Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Sun, 5 Nov 2023 13:53:34 +0100 Subject: [PATCH 320/340] added Welsh (cy) and Chechen (ce) --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index c5404bb1..46dcf17b 100644 --- a/README.rst +++ b/README.rst @@ -80,6 +80,8 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``ar`` (Arabic) * ``az`` (Azerbaijani) * ``by`` (Belarusian) +* ``ce`` (Chechen) +* ``cy`` (Welsh) * ``cz`` (Czech) * ``de`` (German) * ``dk`` (Danish) From 7275bcd725fc8dcacce6b33e62905263ab77b00a Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 9 Nov 2023 13:39:07 +0100 Subject: [PATCH 321/340] pass tox tests (flake8, isort) --- num2words/README.md | 15 ++ num2words/__init__.py | 18 +- num2words/lang_CE.py | 478 +++++++++++++++++++++--------------------- num2words/lang_CY.py | 257 ++++++++++++++--------- tests/test_ce.py | 109 +++++++--- tests/test_cy.py | 83 +++++--- 6 files changed, 544 insertions(+), 416 deletions(-) diff --git a/num2words/README.md b/num2words/README.md index 18558096..9f873881 100644 --- a/num2words/README.md +++ b/num2words/README.md @@ -52,3 +52,18 @@ e.g. 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 +``` + +and run `tox` + +``` +tox +``` + diff --git a/num2words/__init__.py b/num2words/__init__.py index 5641598e..a0dff43b 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,15 +17,15 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BY, - 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_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, - lang_RO, lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE, - lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_AZ, lang_BY, 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_GT, lang_ES_NI, lang_ES_VE, + lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, + lang_HE, lang_HU, lang_ID, lang_IS, lang_IT, lang_JA, lang_KN, + lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, + lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_SK, lang_SL, + lang_SR, lang_SV, lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, + lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), diff --git a/num2words/lang_CE.py b/num2words/lang_CE.py index 0d6c01ef..1e6ed99f 100644 --- a/num2words/lang_CE.py +++ b/num2words/lang_CE.py @@ -16,266 +16,265 @@ from __future__ import unicode_literals +from .currency import parse_currency_parts from .lang_EU import Num2Word_EU -from .currency import parse_currency_parts, prefix_currency # 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 "в". +# 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": "Эрг;", + "abs": "Им.", + "gen": "Род.", + "dat": "Дат.", + "erg": "Эрг;", "instr": "Твор.", - "mat": "Вещ.", - "comp": "Сравнит.", - "all": "Местн.", - }, - "casesuffix_cons": { # to be added to numerals with final consonant - "gen": "аннан", - "dat": "анна", - "erg": "амма", + "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": "мма", + "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": "ноло", + "mat": "ннах", + "comp": "ннал", + "all": "нга", + "obl": "н", + "ORD": "лгӀа", + }, + 0: { + "attr": "ноль", + "abs": "ноль", + "gen": "нолан", + "dat": "нолана", + "erg": "ноло", "instr": "ноланца", - "mat": "ноланах", - "comp": "ноланал", - "all": "ноланга", + "mat": "ноланах", + "comp": "ноланал", + "all": "ноланга", }, 1: { - "attr": "цхьа", # in front of nouns in ABS - "obl": "цхьана", # with nouns in other cases than ABS - "abs": "цхьаъ", - "gen": "цхьаннан", - "dat": "цхьанна", - "erg": "цхьамма", + "attr": "цхьа", # in front of nouns in ABS + "obl": "цхьана", # with nouns in other cases than ABS + "abs": "цхьаъ", + "gen": "цхьаннан", + "dat": "цхьанна", + "erg": "цхьамма", "instr": "цхьаьнца", - "mat": "цхьаннах", - "comp": "цхьаннал", - "all": "цхаьнга", - "ORD": "цхьалгӀа", - }, + "mat": "цхьаннах", + "comp": "цхьаннал", + "all": "цхаьнга", + "ORD": "цхьалгӀа", + }, 2: { - "attr": "ши", #in front of 100, 1000 - "obl": "шина", - "abs": "шиъ", - "gen": "шиннан", - "dat": "шинна", - "erg": "шимма", + "attr": "ши", # in front of 100, 1000 + "obl": "шина", + "abs": "шиъ", + "gen": "шиннан", + "dat": "шинна", + "erg": "шимма", "instr": "шинца", - "mat": "шиннах", - "comp": "шиннал", - "all": "шинга", - "ORD": "шолгӀа", - }, + "mat": "шиннах", + "comp": "шиннал", + "all": "шинга", + "ORD": "шолгӀа", + }, 3: { - "attr": "кхо", - "obl": "кхона", - "abs": "кхоъ", - "gen": "кхааннан", - "dat": "кхаанна", - "erg": "кхаамма", + "attr": "кхо", + "obl": "кхона", + "abs": "кхоъ", + "gen": "кхааннан", + "dat": "кхаанна", + "erg": "кхаамма", "instr": "кхаанца", - "mat": "кхааннах", - "comp": "кхааннал", - "all": "кхаанга", - "ORD": "кхоалгӀа", - - }, + "mat": "кхааннах", + "comp": "кхааннал", + "all": "кхаанга", + "ORD": "кхоалгӀа", + }, 4: { - "attr": "д*и", - "obl": "д*еа", - "abs": "д*иъ", - "gen": "д*еаннан", - "dat": "д*еанна", - "erg": "д*еамма", + "attr": "д*и", + "obl": "д*еа", + "abs": "д*иъ", + "gen": "д*еаннан", + "dat": "д*еанна", + "erg": "д*еамма", "instr": "д*еанца", - "mat": "д*еаннах", - "comp": "д*еаннал", - "all": "д*еанга", - "ORD": "д*оьалгӀа", - }, - + "mat": "д*еаннах", + "comp": "д*еаннал", + "all": "д*еанга", + "ORD": "д*оьалгӀа", + }, 5: { - "attr": "пхи", - "obl": "пхеа", - "abs": "пхиъ", - "gen": "пхеаннан", - "dat": "пхеанна", - "erg": "пхеамма", + "attr": "пхи", + "obl": "пхеа", + "abs": "пхиъ", + "gen": "пхеаннан", + "dat": "пхеанна", + "erg": "пхеамма", "instr": "нхеанца", - "mat": "пхеаннах", - "comp": "пхеаннал", - "all": "пхеанга", - "ORD": "пхоьалгӀа", - }, - + "mat": "пхеаннах", + "comp": "пхеаннал", + "all": "пхеанга", + "ORD": "пхоьалгӀа", + }, 6: { - "abs": "ялх", + "abs": "ялх", "attr": "ялх", - "ORD" : "йолхалгӀа", + "ORD": "йолхалгӀа", }, 7: { - "abs": "ворхӀ", + "abs": "ворхӀ", "attr": "ворхӀ", - "ORD": "ворхӀалгӀа", + "ORD": "ворхӀалгӀа", }, 8: { - "abs": "бархӀ", + "abs": "бархӀ", "attr": "бархӀ", - "ORD": "борхӀалӀа", + "ORD": "борхӀалӀа", }, 9: { - "abs": "исс", + "abs": "исс", "attr": "исс", - "ORD": "уьссалгӀа", + "ORD": "уьссалгӀа", }, 10: { - "attr": "итт", - "abs": "итт", - "gen": "иттаннан", - "dat": "иттанна", - "erg": "иттамма", + "attr": "итт", + "abs": "итт", + "gen": "иттаннан", + "dat": "иттанна", + "erg": "иттамма", "instr": "иттанца", - "mat": "иттаннах", - "comp": "иттаннал", - "all": "иттанга", - "ORD": "уьтталгӀа", - }, + "mat": "иттаннах", + "comp": "иттаннал", + "all": "иттанга", + "ORD": "уьтталгӀа", + }, 11: { - "abs": "цхьайтта", + "abs": "цхьайтта", "attr": "цхьайтта", - "ORD": "цхьайтталгӀа", - }, + "ORD": "цхьайтталгӀа", + }, 12: { - "abs": "шийтта", + "abs": "шийтта", "attr": "шийтта", - "ORD": "шийтталга", - }, + "ORD": "шийтталга", + }, 13: { - "abs": "кхойтта", + "abs": "кхойтта", "attr": "кхойтта", - "ORD": "кхойтталгӀа", - }, + "ORD": "кхойтталгӀа", + }, 14: { - "abs": "д*ейтта", + "abs": "д*ейтта", "attr": "д*ейтта", - "ORD": "д*ейтталгӀа", - }, + "ORD": "д*ейтталгӀа", + }, 15: { - "abs": "пхийтта", + "abs": "пхийтта", "attr": "пхийтта", - "ORD": "пхийтталгӀа", - }, + "ORD": "пхийтталгӀа", + }, 16: { - "abs": "ялхитта", + "abs": "ялхитта", "attr": "ялхитта", - "ORD": "ялхитталгӀа", - }, + "ORD": "ялхитталгӀа", + }, 17: { - "abs": "вуьрхӀитта", + "abs": "вуьрхӀитта", "attr": "вуьрхӀитта", - "ORD": "вуьрхӀитталгӀа", - }, + "ORD": "вуьрхӀитталгӀа", + }, 18: { - "abs": "берхӀитта", + "abs": "берхӀитта", "attr": "берхӀитта", - "ORD": "берхитталӀа", - }, + "ORD": "берхитталӀа", + }, 19: { - "abs": "ткъайесна", + "abs": "ткъайесна", "attr": "ткъайесна", - "ORD": "ткъаесналгӀа", - }, + "ORD": "ткъаесналгӀа", + }, 20: { - "abs": "ткъа", - "gen": "ткъаннан", - "dat": "ткъанна", - "erg": "ткъамма", + "abs": "ткъа", + "gen": "ткъаннан", + "dat": "ткъанна", + "erg": "ткъамма", "instr": "ткъанца", - "mat": "ткъаннах", - "comp": "ткъаннал", - "all": "ткъанга", - "attr": "ткъе", - "ORD": "ткъолгӀа", - }, + "mat": "ткъаннах", + "comp": "ткъаннал", + "all": "ткъанга", + "attr": "ткъе", + "ORD": "ткъолгӀа", + }, 40: { - "abs": "шовзткъа", + "abs": "шовзткъа", "attr": "шовзткъе", - "ORD": "шовзткъалгІа", - }, + "ORD": "шовзткъалгІа", + }, 60: { - "abs": "кхузткъа", + "abs": "кхузткъа", "attr": "кхузткъе", - "ORD": "кхузткъалгІа", - }, + "ORD": "кхузткъалгІа", + }, 80: { - "abs": "дезткъа", + "abs": "дезткъа", "attr": "дезткъе", - "ORD": "дезткъалгІа", - }, + "ORD": "дезткъалгІа", + }, 100: { - "attr": "бӀе", - "abs": "бӀе", - "obl": "бӀен", - "gen": "бӀеннан", - "dat": "бӀенна", - "erg": "бӀемма", + "attr": "бӀе", + "abs": "бӀе", + "obl": "бӀен", + "gen": "бӀеннан", + "dat": "бӀенна", + "erg": "бӀемма", "instr": "бӀенца", - "mat": "бӀеннах", - "comp": "бӀеннал", - "all": "бӀенга", - "ORD": "бІолгІа", - }, + "mat": "бӀеннах", + "comp": "бӀеннал", + "all": "бӀенга", + "ORD": "бІолгІа", + }, 1000: { - "attr": "эзар", - "abs": "эзар", - "obl": "эзаран", - "gen": "эзарнан", - "dat": "эзарна", - "erg": "эзарно", + "attr": "эзар", + "abs": "эзар", + "obl": "эзаран", + "gen": "эзарнан", + "dat": "эзарна", + "erg": "эзарно", "instr": "эзарнаца", - "mat": "эзарнах", - "comp": "эзарнал", - "all": "эзаранга", - "ORD": "эзарлагІа", - }, + "mat": "эзарнах", + "comp": "эзарнал", + "all": "эзаранга", + "ORD": "эзарлагІа", + }, 1000000: { "attr": "миллион", "abs": "миллион", "ORD": "миллионалгІа", - } - } - + }, +} + ILLIONS = { 6: { "attr": "миллион", @@ -331,17 +330,17 @@ MINUS = "минус" -DECIMALPOINT = "запятая" # check ! +DECIMALPOINT = "запятая" # check ! + class Num2Word_CE(Num2Word_EU): CURRENCY_FORMS = { # currency code: (sg, pl), (sg, pl) - - 'EUR': (('Евро', 'Евро'), ("Сент", "Сенташ")), - 'RUB': (("Сом", "Сомаш"), ("Кепек", "Кепекаш")), - 'USD': (("Доллар", "Доллараш"), ("Сент", "Сенташ")), - 'GBP': (("Фунт", "Фунташ"), ("Пенни", "Пенни")) - } + "EUR": (("Евро", "Евро"), ("Сент", "Сенташ")), + "RUB": (("Сом", "Сомаш"), ("Кепек", "Кепекаш")), + "USD": (("Доллар", "Доллараш"), ("Сент", "Сенташ")), + "GBP": (("Фунт", "Фунташ"), ("Пенни", "Пенни")), + } def setup(self): Num2Word_EU.setup(self) @@ -350,35 +349,27 @@ def __init__(self): pass def to_ordinal(self, number, clazz="д"): - # implement here your code. number is the integer to be transformed into an ordinal - # as a word (str) + # 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] + 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: - #if case in CARDINALS[number]: - # return CARDINALS[number][case] - #else: - # add casesuffix to ABS stem return self.makecase(number, case, clazz) - #if CARDINALS[number]["abs"][-1] in "а": - # return CARDINALS[number]["abs"] + CARDINALS["casesuffix_voc"][case] - #else: - # return CARDINALS[number]["abs"] + CARDINALS["casesuffix_cons"][case] elif number < 100: twens = number // 20 units = number % 20 - base = twens*20 + base = twens * 20 if units == 0: return self.makecase(number, case, clazz) else: @@ -389,7 +380,9 @@ def to_cardinal(self, number, clazz="д", case="abs"): hundreds = number // 100 tens = number % 100 if hundreds > 1: - hundert = CARDINALS[hundreds]["attr"].replace("д*", clazz) + " " + hundert = ( + CARDINALS[hundreds]["attr"].replace("д*", clazz) + " " + ) else: hundert = "" if tens != 0: @@ -405,7 +398,11 @@ def to_cardinal(self, number, clazz="д", case="abs"): else: tcase = case if thousands > 1: - tausend = self.to_cardinal(thousands, clazz=clazz, case="attr") + " " + CARDINALS[1000][tcase] + tausend = ( + self.to_cardinal(thousands, clazz=clazz, case="attr") + + " " + + CARDINALS[1000][tcase] + ) else: tausend = self.makecase(1000, tcase, clazz) @@ -417,7 +414,7 @@ def to_cardinal(self, number, clazz="д", case="abs"): elif number < 10**34: out = [] - for pot in reversed([6,9,12,15,18,21,24,27,30,33]): + 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: @@ -431,19 +428,26 @@ def to_cardinal(self, number, clazz="д", case="abs"): return "NOT IMPLEMENTED" def _money_verbose(self, number, currency, case): - mcase ="attr" + mcase = "attr" if case != "abs": mcase = "obl" return self.to_cardinal(number, case=mcase) def _cents_verbose(self, number, currency, case): - mcase ="attr" + mcase = "attr" if case != "abs": mcase = "obl" - return self.to_cardinal(number, case="attr") + return self.to_cardinal(number, case=mcase) - def to_currency(self, val, currency='RUB', cents=True, separator=',', - adjective=False, case="abs"): + def to_currency( + self, + val, + currency="RUB", + cents=True, + separator=",", + adjective=False, + case="abs", + ): """ Args: val: Numeric value @@ -461,49 +465,41 @@ def to_currency(self, val, currency='RUB', cents=True, separator=',', cr1, cr2 = self.CURRENCY_FORMS[currency] devise = cr1[0] centime = cr2[0] - #if case != "abs": - # if devise[-1] in "аеиоуяю": - # devise += CARDINALS["casesuffix_voc"][case] - # else: - # devise += CARDINALS["casesuffix_cons"][case] - # if centime[-1] in "аеиоуяю": - # centime += CARDINALS["casesuffix_voc"][case] - # else: - # centime += CARDINALS["casesuffix_cons"][case] 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) + '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) - - - + cents_str = ( + self._cents_verbose(right, currency, case) + if cents + else self._cents_terse(right, currency) + ) - return u'%s%s %s%s %s %s' % ( + return "%s%s %s%s %s %s" % ( minus_str, money_str, - devise, # always singular + devise, # always singular separator, cents_str, - centime + centime, ) - def makecase(self, number, case, clazz): - #print("ZZZZ", number, CARDINALS[number]) + # 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] + return ( + CARDINALS[number]["abs"].replace("д*", clazz) + + CARDINALS["casesuffix_voc"][case] + ) else: - return CARDINALS[number]["abs"].replace("д*", clazz) + CARDINALS["casesuffix_cons"][case] - - + return ( + CARDINALS[number]["abs"].replace("д*", clazz) + + CARDINALS["casesuffix_cons"][case] + ) diff --git a/num2words/lang_CY.py b/num2words/lang_CY.py index 6d6f3b1e..987b321d 100644 --- a/num2words/lang_CY.py +++ b/num2words/lang_CY.py @@ -16,8 +16,8 @@ from __future__ import unicode_literals -from .lang_EU import Num2Word_EU from .currency import parse_currency_parts, prefix_currency +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 @@ -89,12 +89,12 @@ 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)], + 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 @@ -118,22 +118,21 @@ 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), - } +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)], @@ -151,7 +150,7 @@ 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)], + 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)], @@ -173,7 +172,7 @@ 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)], + 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)], @@ -181,39 +180,49 @@ } # 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) +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') + +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')), + "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 " @@ -228,18 +237,22 @@ def float_to_words(self, float_number, ordinal=False): prefix = self.to_ordinal(int(float_number)) else: prefix = self.to_cardinal(int(float_number)) - float_part = str(float_number).split('.')[1] + 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): + def hundred_group( + self, number, informal=False, gender="masc", ordinal=False + ): hundreds = number // 100 - until100 = number % 100 # 0 - 99 - result = [] # list group of number words and mutation info (for the following word) + 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: @@ -253,7 +266,24 @@ def hundred_group(self, number, informal=False, gender="masc", ordinal=False): 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]: + 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")) @@ -274,14 +304,17 @@ def hundred_group(self, number, informal=False, gender="masc", ordinal=False): if units == 0: result.extend([("hanner cant", None), (OBJ, None)]) elif units == 1: - result.extend([("hanner cant ac un", None), (OBJ, None)]) + 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 (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)]) @@ -293,7 +326,6 @@ def hundred_group(self, number, informal=False, gender="masc", ordinal=False): degau = ORD_STR_TENS.get(tens) else: degau = STR_TENS.get(tens) - #print("BBBB", number, tens, degau) #, softmutation(degau)) if units != 0: if tens > 1: @@ -310,9 +342,6 @@ def hundred_group(self, number, informal=False, gender="masc", ordinal=False): result.extend(degau) return result - - - def to_ordinal(self, number, informal=False, gender="masc"): if number < 20: return makestring(ORDINAL_WORDS[number]) @@ -321,10 +350,19 @@ def to_ordinal(self, number, informal=False, gender="masc"): elif number > 100: raise NotImplementedError("The given number is too large.") - return self.to_cardinal(number, informal=False, gender=gender, ordinal=True) - + 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): + def to_cardinal( + self, + number, + informal=False, + gender="masc", + ordinal=False, + counted=None, + raw=False, + ): negative = False if number < 0: negative = True @@ -341,35 +379,46 @@ def to_cardinal(self, number, informal=False, gender="masc", ordinal=False, coun return self.float_to_words(number) # split in groups of 10**3 - groups = [] # groups of three digits starting from right (units (1 - 999), thousands, millions, .. - 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 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) + # print("groups", groups) result = [] if negative: result.append(("meinws", None)) - - for gr,pot in reversed(groups): + + for gr, pot in reversed(groups): if gr: - #print("AAAA", gr, pot, gender) + # print("AAAA", gr, pot, gender) if pot == 6: - g = "fem" # mil (1000) is feminine + g = "fem" # mil (1000) is feminine elif pot == 3: - g = gender # units depend on the following noun + g = gender # units depend on the following noun else: - g = "masc" # millions etc are masculine + 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)) + 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]) + result.append(MILLION_WORDS[pot - 3]) if raw: # need to be able trigger correct mutation on currencies return result @@ -381,8 +430,9 @@ def to_cardinal(self, number, informal=False, gender="masc", ordinal=False, coun result.extend([("o", "SM"), (counted, None)]) return makestring(result) - def to_currency(self, val, currency='EUR', cents=True, separator=',', - adjective=False): + def to_currency( + self, val, currency="EUR", cents=True, separator=",", adjective=False + ): """ Args: val: Numeric value @@ -400,43 +450,48 @@ def to_currency(self, val, currency='EUR', cents=True, separator=',', except KeyError: raise NotImplementedError( - 'Currency code "%s" not implemented for "%s"' % - (currency, self.__class__.__name__)) + '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) + cents_str = ( + self._cents_verbose(right, currency) + if cents + else self._cents_terse(right, currency) + ) if right == 0: # no pence - return u'%s%s' % ( + return "%s%s" % ( minus_str, money_str, - #self.pluralize(right, cr2) - ) + # self.pluralize(right, cr2) + ) elif left == 0: # no pence - return u'%s%s' % ( + return "%s%s" % ( minus_str, cents_str, - #self.pluralize(right, cr2) - ) + # self.pluralize(right, cr2) + ) - return u'%s%s%s %s' % ( + return "%s%s%s %s" % ( minus_str, money_str, - #self.pluralize(left, cr1), + # self.pluralize(left, cr1), separator, cents_str, - #self.pluralize(right, cr2) + # self.pluralize(right, cr2) ) def _money_verbose(self, number, currency): - # used in super().to_currency(), we need to add gender here for feminine currenceis + # used in super().to_currency(), we need to add gender + # here for feminine currencies if currency in CURRENCIES_FEM: if number > 100: m = self.to_cardinal(number, gender="fem", raw=True) @@ -450,26 +505,25 @@ def _money_verbose(self, number, currency): return makestring(m) else: if number > 1: - m = self.to_cardinal(number, gender="fem", raw=True) + 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) + # 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) + m = self.to_cardinal(number, raw=True) if currency in self.CURRENCY_FORMS: c = self.CURRENCY_FORMS[currency][0][1] m.append(("o", "SM")) @@ -480,16 +534,13 @@ def _cents_verbose(self, number, currency): return makestring(m) else: if number > 1: - m = self.to_cardinal(number, raw=True) + 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 - #print("eeeeeeeee", m) - #m.append((c, None)) - #print("fffffffff", m) return makestring(m, counted=c) @@ -503,24 +554,26 @@ def makestring(result, counted=None): continue else: w = counted - counted = None # only first position + 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", number, word) + # print("uuu", number, word) if mutation == "SM": return softmutation(word) elif mutation == "AM": return aspiratedmutation(word) return word + def softmutation(word): - #print("SM<<<<%s>" % 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": @@ -542,6 +595,7 @@ def softmutation(word): else: return word + def aspiratedmutation(word): if word[0] == "p" and word[1] != "h": return "ph" + word[1:] @@ -551,6 +605,3 @@ def aspiratedmutation(word): return "ch" + word[1:] else: return word - -#def omitt_if_zero(number_to_string): -# return "" if number_to_string == ZERO else number_to_string diff --git a/tests/test_ce.py b/tests/test_ce.py index f4f71ae1..4286c5d5 100644 --- a/tests/test_ce.py +++ b/tests/test_ce.py @@ -120,7 +120,6 @@ (97, "erg", "д", "дезткъе вуьрхӀиттамма"), (98, "instr", "й", "дезткъе берхӀиттанца"), (99, "instr", "б", "дезткъе ткъайеснанца"), - (0, "gen", "б", "нолан"), (100, "mat", "б", "бӀеннах"), (200, "attr", "д", "ши бӀе"), @@ -145,7 +144,7 @@ (2022, "comp", "д", "ши эзар ткъе шиннал"), (2100, "obl", "в", "ши эзар бӀен"), (423000, "erg", "в", "ви бӀе ткъе кхо эзарно"), - ] +] TEST_CASES_ORDINAL = [ (1, "all", "б", "цхьалгӀа"), @@ -278,11 +277,9 @@ (2033, "all", "д", "ши эзар ткъе кхойтталгӀа"), (2140, "dat", "б", "ши эзар бӀе шовзткъалгІа"), (423000, "dat", "д", "ди бӀе ткъе кхо эзарлагІа"), - ] +] -TEST_CASES_DECIMALS = [ - (123.4567, "бӀе ткъе кхоъ запятая диъ пхиъ ялх ворхӀ") - ] +TEST_CASES_DECIMALS = [(123.4567, "бӀе ткъе кхоъ запятая диъ пхиъ ялх ворхӀ")] TEST_CASES_MILLIONS = [ (200020, "ши бӀе эзар ткъа"), @@ -297,48 +294,100 @@ (2000200000000000, "ши биллиард ши бӀе миллиард"), (22002200000000000, "ткъе ши биллиард ши биллион ши бӀе миллиард"), (240024000000000000, "ши бӀе шовзткъе биллиард ткъе ди биллион"), - (2600260000000000000, "ши триллион ялх бӀе биллиард ши бӀе кхузткъе биллион"), - (28002800000000000000, "ткъе бархӀ триллион ши биллиард бархӀ бӀе биллион"), + ( + 2600260000000000000, + "ши триллион ялх бӀе биллиард ши бӀе кхузткъе биллион", + ), + ( + 28002800000000000000, + "ткъе бархӀ триллион ши биллиард бархӀ бӀе биллион", + ), (300030000000000000000, "кхо бӀе триллион ткъе итт биллиард"), - (3200320000000000000000, "кхо триллиард ши бӀе триллион кхо бӀе ткъе биллиард"), - (34003400000000000000000, "ткъе дейтта триллиард кхо триллион ди бӀе биллиард"), - (360036000000000000000000, "кхо бӀе кхузткъе триллиард ткъе ялхитта триллион"), - (3800380000000000000000000, "кхо квадриллион бархӀ бӀе триллиард кхо бӀе дезткъе триллион"), + ( + 3200320000000000000000, + "кхо триллиард ши бӀе триллион кхо бӀе ткъе биллиард", + ), + ( + 34003400000000000000000, + "ткъе дейтта триллиард кхо триллион ди бӀе биллиард", + ), + ( + 360036000000000000000000, + "кхо бӀе кхузткъе триллиард ткъе ялхитта триллион", + ), + ( + 3800380000000000000000000, + "кхо квадриллион бархӀ бӀе триллиард кхо бӀе дезткъе триллион", + ), (40004000000000000000000000, "шовзткъе квадриллион ди триллиард"), - (420042000000000000000000000, "ди бӀе ткъе квадриллион шовзткъе ши триллиард"), - (4400440000000000000000000000, "ди квадриллиард ди бӀе квадриллион ди бӀе шовзткъе триллиард"), - (46004600000000000000000000000, "шовзткъе ялх квадриллиард ди квадриллион ялх бӀе триллиард"), - (480048000000000000000000000000, "ди бӀе дезткъе квадриллиард шовзткъе бархӀ квадриллион"), + ( + 420042000000000000000000000, + "ди бӀе ткъе квадриллион шовзткъе ши триллиард", + ), + ( + 4400440000000000000000000000, + "ди квадриллиард ди бӀе квадриллион ди бӀе шовзткъе триллиард", + ), + ( + 46004600000000000000000000000, + "шовзткъе ялх квадриллиард ди квадриллион ялх бӀе триллиард", + ), + ( + 480048000000000000000000000000, + "ди бӀе дезткъе квадриллиард шовзткъе бархӀ квадриллион", + ), (5000500000000000000000000000000, "пхи квинтиллион пхи бӀе квадриллион"), - (52005200000000000000000000000000, "шовзткъе шийтта квинтиллион пхи квадриллиард ши бӀе квадриллион"), - (540054000000000000000000000000000, "пхи бӀе шовзткъе квинтиллион шовзткъе дейтта квадриллиард"), - (5600560000000000000000000000000000, "пхи квинтиллиард ялх бӀе квинтиллион пхи бӀе кхузткъе квадриллиард"), - ] + ( + 52005200000000000000000000000000, + "шовзткъе шийтта квинтиллион пхи квадриллиард ши бӀе квадриллион", + ), + ( + 540054000000000000000000000000000, + "пхи бӀе шовзткъе квинтиллион шовзткъе дейтта квадриллиард", + ), + ( + 5600560000000000000000000000000000, + "пхи квинтиллиард ялх бӀе квинтиллион пхи бӀе кхузткъе квадриллиард", + ), +] TEST_CURRENCY = [ - (143.55, "abs", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), - ] + (143.55, "abs", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), +] -class Num2WordsCETest(TestCase): +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]) + 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]) + 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(test[0], lang="ce", to="ordinal", clazz=test[2]), + test[3], + ) def test_currency(self): for test in TEST_CURRENCY: - self.assertEqual(num2words(test[0], lang='ce', to="currency", currency="RUB", case=test[1]), test[2]) + self.assertEqual( + num2words( + test[0], + lang="ce", + to="currency", + currency="RUB", + case=test[1], + ), + test[2], + ) def test_decimals(self): for test in TEST_CASES_DECIMALS: - self.assertEqual(num2words(test[0], lang='ce'), test[1]) - - + self.assertEqual(num2words(test[0], lang="ce"), test[1]) diff --git a/tests/test_cy.py b/tests/test_cy.py index 7242df52..4ca9ed0e 100644 --- a/tests/test_cy.py +++ b/tests/test_cy.py @@ -145,7 +145,6 @@ (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"), @@ -154,7 +153,6 @@ (685, "chwech chant a phump a phedwar ugain"), (802, "wyth cant a dau"), (919, "naw cant a phedwar ar bymtheg"), - (100, "cant"), (200, "dau gant"), (300, "tri chant"), @@ -165,11 +163,13 @@ (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"), + ( + 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"), @@ -178,26 +178,37 @@ (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"), + ( + 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"), + ( + 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 = ( @@ -366,21 +377,21 @@ (98, "deunawfed a phedwar ugain"), (99, "pedwerydd ar bymtheg a phedwar ugain"), (100, "canfed"), - ) +) TEST_CASES_DECIMALS = [ (123.4567, "cant a thri ar hugain pwynt pedwar pump chwech saith") - ] +] TEST_CASES_TO_CURRENCY_GBP = ( - (2.04, 'dwy bunt, pedwar ceiniog'), - (3.50, 'tair punt, hanner cant ceiniog'), - (2002.15, 'dwy fil dwy o bunnoedd, pymtheg ceiniog'), + (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") - ) + (152.50, "cant a hanner a dwy o bunnoedd, hanner cant ceiniog"), +) TEST_CASES_COUNTED = [ (2, "ci", "masc", "dau gi"), @@ -395,36 +406,42 @@ (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]) + 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]) + self.assertEqual( + num2words(test[0], lang="cy", gender="fem"), test[1] + ) def test_decimals(self): for test in TEST_CASES_DECIMALS: - self.assertEqual(num2words(test[0], lang='cy'), test[1]) - + 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]) + self.assertEqual( + num2words(test[0], lang="cy", to="ordinal"), test[1] + ) 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]) - + self.assertEqual( + num2words(test[0], lang="cy", to="currency", currency="GBP"), + test[1], + ) 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]) - - - + self.assertEqual( + num2words( + test[0], lang="cy", counted=test[1], gender=test[2] + ), + test[3], + ) From f79af95e224adcc9b9e9182428cde38994b3bc47 Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 9 Nov 2023 14:29:22 +0100 Subject: [PATCH 322/340] added support for "to_ordinal_num" and "year" --- num2words/lang_CE.py | 7 +++++++ tests/test_ce.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/num2words/lang_CE.py b/num2words/lang_CE.py index 1e6ed99f..efe1614c 100644 --- a/num2words/lang_CE.py +++ b/num2words/lang_CE.py @@ -488,6 +488,13 @@ def to_currency( 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]: diff --git a/tests/test_ce.py b/tests/test_ce.py index 4286c5d5..a91c5c63 100644 --- a/tests/test_ce.py +++ b/tests/test_ce.py @@ -279,6 +279,12 @@ (423000, "dat", "д", "ди бӀе ткъе кхо эзарлагІа"), ] +TEST_CASES_YEAR = [ + (1719, "abs", "эзар ворхӀ бӀе ткъайесна"), + (1812, "abs", "эзар бархӀ бӀе шийтта"), + (1926, "abs", "эзар исс бӀе ткъе ялх"), +] + TEST_CASES_DECIMALS = [(123.4567, "бӀе ткъе кхоъ запятая диъ пхиъ ялх ворхӀ")] TEST_CASES_MILLIONS = [ @@ -374,6 +380,15 @@ def test_ordinal_number(self): 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: From d5bca219e929433b564d8384f4248a4b0cc837be Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 9 Nov 2023 16:17:10 +0100 Subject: [PATCH 323/340] improved floats, increased test coverage --- num2words/lang_CE.py | 20 +++++++++++++++----- tests/test_ce.py | 20 +++++++++++++------- tests/test_cy.py | 10 ++++++++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/num2words/lang_CE.py b/num2words/lang_CE.py index efe1614c..abf8e5f0 100644 --- a/num2words/lang_CE.py +++ b/num2words/lang_CE.py @@ -330,7 +330,8 @@ MINUS = "минус" -DECIMALPOINT = "запятая" # check ! +# DECIMALPOINT = "запятая" # check ! +DECIMALPOINT = "а" class Num2Word_CE(Num2Word_EU): @@ -344,9 +345,18 @@ class Num2Word_CE(Num2Word_EU): def setup(self): Num2Word_EU.setup(self) - - def __init__(self): - pass + 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 @@ -490,7 +500,7 @@ def to_currency( def to_ordinal_num(self, number): self.verify_ordinal(number) - return str(number) + "." + return str(number) + "-й" def to_year(self, year, case="abs"): return self.to_cardinal(year, case=case) diff --git a/tests/test_ce.py b/tests/test_ce.py index a91c5c63..7deddfe6 100644 --- a/tests/test_ce.py +++ b/tests/test_ce.py @@ -285,7 +285,7 @@ (1926, "abs", "эзар исс бӀе ткъе ялх"), ] -TEST_CASES_DECIMALS = [(123.4567, "бӀе ткъе кхоъ запятая диъ пхиъ ялх ворхӀ")] +TEST_CASES_DECIMALS = [(123.4567, "бӀе ткъе кхоъ а диъ пхиъ ялх ворхӀ")] TEST_CASES_MILLIONS = [ (200020, "ши бӀе эзар ткъа"), @@ -355,10 +355,12 @@ 5600560000000000000000000000000000, "пхи квинтиллиард ялх бӀе квинтиллион пхи бӀе кхузткъе квадриллиард", ), + (10**56, "NOT IMPLEMENTED") ] TEST_CURRENCY = [ - (143.55, "abs", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), + (143.55, "abs", "RUB", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), + (243.15, "dat", "RUB", "ши бӀе шовзткъе кхона Сом, пхийттан Кепек"), ] @@ -380,9 +382,9 @@ def test_ordinal_number(self): 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.") + 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: @@ -397,12 +399,16 @@ def test_currency(self): test[0], lang="ce", to="currency", - currency="RUB", + currency=test[2], case=test[1], ), - test[2], + 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_cy.py b/tests/test_cy.py index 4ca9ed0e..ff47d031 100644 --- a/tests/test_cy.py +++ b/tests/test_cy.py @@ -379,6 +379,14 @@ (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") ] @@ -445,3 +453,5 @@ def test_counted(self): ), test[3], ) + +# TODO 'ordinal_num', 'year' From 28e3f0ef240db13fa9a315efcd4dce119f0b5c5d Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 9 Nov 2023 17:25:23 +0100 Subject: [PATCH 324/340] coverage trying to improve ... --- num2words/lang_CY.py | 26 ++++++++++++++------------ tests/test_cy.py | 6 ++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/num2words/lang_CY.py b/num2words/lang_CY.py index 987b321d..f38c7a5e 100644 --- a/num2words/lang_CY.py +++ b/num2words/lang_CY.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals -from .currency import parse_currency_parts, prefix_currency +from .currency import parse_currency_parts from .lang_EU import Num2Word_EU # Welsh numerals differs to many other languages since the counted @@ -232,11 +232,11 @@ def setup(self): def __init__(self): pass - def float_to_words(self, float_number, ordinal=False): - if ordinal: - prefix = self.to_ordinal(int(float_number)) - else: - prefix = self.to_cardinal(int(float_number)) + 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 @@ -288,9 +288,9 @@ def hundred_group( else: result.append(("a", "AM")) if until100: - if informal: - pass - elif not ordinal and until100 >= 50 and until100 <= 59: + # if informal: + # pass + if not ordinal and until100 >= 50 and until100 <= 59: units = number % 10 if hundreds > 0: if units == 0: @@ -454,8 +454,8 @@ def to_currency( % (currency, self.__class__.__name__) ) - if adjective and currency in self.CURRENCY_ADJECTIVES: - cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1) + # 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) @@ -473,7 +473,7 @@ def to_currency( # self.pluralize(right, cr2) ) elif left == 0: - # no pence + # no pounds return "%s%s" % ( minus_str, cents_str, @@ -506,6 +506,8 @@ def _money_verbose(self, number, currency): 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: diff --git a/tests/test_cy.py b/tests/test_cy.py index ff47d031..d8196709 100644 --- a/tests/test_cy.py +++ b/tests/test_cy.py @@ -154,6 +154,7 @@ (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"), @@ -392,6 +393,7 @@ ] TEST_CASES_TO_CURRENCY_GBP = ( + (0.00, "dim punt"), (2.04, "dwy bunt, pedwar ceiniog"), (3.50, "tair punt, hanner cant ceiniog"), (2002.15, "dwy fil dwy o bunnoedd, pymtheg ceiniog"), @@ -428,6 +430,10 @@ def test_number_fem(self): 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]) From b0547a13a2b14fd13b42b1cb4b9396991a9535c2 Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 9 Nov 2023 20:41:11 +0100 Subject: [PATCH 325/340] improved coverage tests do pass in 333->343, 341->343, 572->exit but coverage marks as not testes --- num2words/README.md | 3 +- num2words/lang_CY.py | 92 ++++++++++++++++++++++---------------------- tests/test_cy.py | 12 ++++++ 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/num2words/README.md b/num2words/README.md index 9f873881..b7e2e0fa 100644 --- a/num2words/README.md +++ b/num2words/README.md @@ -61,9 +61,10 @@ For this install the packages needed to test pip install -r requirements-test.txt ``` -and run `tox` +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/lang_CY.py b/num2words/lang_CY.py index f38c7a5e..e5045129 100644 --- a/num2words/lang_CY.py +++ b/num2words/lang_CY.py @@ -226,8 +226,8 @@ class Num2Word_CY(Num2Word_EU): MINUS_PREFIX_WORD = "meinws " FLOAT_INFIX_WORD = " pwynt " - def setup(self): - Num2Word_EU.setup(self) +# def setup(self): +# Num2Word_EU.setup(self) def __init__(self): pass @@ -492,57 +492,57 @@ def to_currency( 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: - 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) + # 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: - return self.to_cardinal(number, raw=True) + # 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) + # 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 + # if currency in self.CURRENCY_FORMS: + c = self.CURRENCY_FORMS[currency][1][0] + # else: + # c = currency return makestring(m, counted=c) @@ -566,12 +566,12 @@ def makestring(result, counted=None): def mutate(word, mutation): - # print("uuu", number, word) + # print("uuu", word, mutation) if mutation == "SM": return softmutation(word) elif mutation == "AM": return aspiratedmutation(word) - return word + # return word # does not occur def softmutation(word): @@ -584,8 +584,6 @@ def softmutation(word): return "g" + word[1:] elif word[0] == "b" or word[0] == "m": return "f" + word[1:] - elif word[0] == "h": - return word[1:] elif word[0] == "d" and word[1] != "d": return "d" + word elif word.startswith("ll"): diff --git a/tests/test_cy.py b/tests/test_cy.py index d8196709..3f7ee038 100644 --- a/tests/test_cy.py +++ b/tests/test_cy.py @@ -394,6 +394,7 @@ 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"), @@ -405,6 +406,9 @@ 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"), @@ -444,6 +448,10 @@ def test_ordinals(self): 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( @@ -451,6 +459,10 @@ def test_pounds(self): 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( From 605b260f830c14a2032da6b7bd831f1ca4b7db76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=A4ufl?= Date: Mon, 13 Nov 2023 17:10:05 +0100 Subject: [PATCH 326/340] Run tests against Python 3.12 --- .github/workflows/ci.yml | 2 +- setup.py | 1 + tox.ini | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 159b7ebe..68330d4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] + python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index af434625..4ca9fda6 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ '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', diff --git a/tox.ini b/tox.ini index 8e334bcf..63e88f3a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39,py310,py311,flake8,isort +envlist = py37,py38,py39,py310,py311,py312,flake8,isort [gh-actions] python = @@ -8,6 +8,7 @@ python = 3.9: py39 3.10: isort, flake8, py310 3.11: py311 + 3.12: py312 [testenv] From 430302930ce889d353a22af1d9ff0c189605bc8b Mon Sep 17 00:00:00 2001 From: Randall Castro Date: Wed, 6 Mar 2024 13:29:12 -0600 Subject: [PATCH 327/340] [ADD] .gitignore: to exclude build artifacts and IDE files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2a9b1bf8..8f01013f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ dist /.tox .eggs/ /venv/ +.venv/ From d63741d985144b77edecd93b39a44ad0965b0427 Mon Sep 17 00:00:00 2001 From: Randall Castro Date: Wed, 6 Mar 2024 13:34:03 -0600 Subject: [PATCH 328/340] [ADD] num2words: es_CR language added --- README.rst | 1 + num2words/__init__.py | 13 +++++---- num2words/lang_ES_CR.py | 30 ++++++++++++++++++++ tests/test_es_cr.py | 61 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 num2words/lang_ES_CR.py create mode 100644 tests/test_es_cr.py diff --git a/README.rst b/README.rst index c5404bb1..0ed664ea 100644 --- a/README.rst +++ b/README.rst @@ -88,6 +88,7 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``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) diff --git a/num2words/__init__.py b/num2words/__init__.py index 789af300..693b0b01 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -19,12 +19,12 @@ from . import (lang_AM, lang_AR, lang_AZ, lang_BY, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, - lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, - lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, - lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, - lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, - lang_RO, lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE, - lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) + 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_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), @@ -45,6 +45,7 @@ '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(), 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/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] + ) From 69dd3e8a012f596c0ed96ea365a413fab0ff96aa Mon Sep 17 00:00:00 2001 From: Johannes Heinecke Date: Thu, 28 Mar 2024 13:21:44 +0100 Subject: [PATCH 329/340] reformated imports since isort complained --- num2words/__init__.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 1f586b20..95dbcd7a 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,14 +17,15 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BY, 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_TG, lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_AZ, lang_BY, 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_TG, lang_TH, + lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From ffebd91cdf19d1ffca0f8706ca764f3ea5e4e99b Mon Sep 17 00:00:00 2001 From: GemmaMassonisRecog <158456439+GemmaMassonisRecog@users.noreply.github.com> Date: Wed, 24 Jul 2024 20:35:03 +0200 Subject: [PATCH 330/340] Add catalan language support (#581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lang_CA * Flake8 * From "" to '' * Delete settings * Delete .coverage * Refactor Num2Word_CA to remove redundant code and include new tests in japanese language --------- Co-authored-by: Alberto Castaño --- num2words/__init__.py | 21 +- num2words/lang_CA.py | 476 ++++++++++++++++++++++++++++++++++++++++++ tests/test_ca.py | 186 +++++++++++++++++ tests/test_ja.py | 18 ++ 4 files changed, 691 insertions(+), 10 deletions(-) create mode 100644 num2words/lang_CA.py create mode 100644 tests/test_ca.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 95dbcd7a..43616cce 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,21 +17,22 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BY, 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_TG, lang_TH, - lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_AZ, lang_BY, 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_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(), 'by': lang_BY.Num2Word_BY(), + 'ca': lang_CA.Num2Word_CA(), 'ce': lang_CE.Num2Word_CE(), 'cy': lang_CY.Num2Word_CY(), 'cz': lang_CZ.Num2Word_CZ(), @@ -80,7 +81,7 @@ 'uk': lang_UK.Num2Word_UK(), 'te': lang_TE.Num2Word_TE(), 'hu': lang_HU.Num2Word_HU(), - 'is': lang_IS.Num2Word_IS() + 'is': lang_IS.Num2Word_IS(), } CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] 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/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_ja.py b/tests/test_ja.py index 42da1445..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): @@ -196,3 +197,20 @@ def test_year(self): "きげんぜんきゅうじゅうくねん") 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)) From e5aee87d12667c8d9a15a2cbccae24a3357d94d1 Mon Sep 17 00:00:00 2001 From: PeteCoward Date: Fri, 20 Sep 2024 22:14:47 +0800 Subject: [PATCH 331/340] Adding Tetum Language (#576) * Initial Tetum copy of PT * ida too sanulu * Up to 999? * up to 9999? * up to 100000 * up to 19000000000 * change milaun to millaun * add trillaun rua * up to 145254635102 * changed trillaun an billaun * changed iliao to illaun * millaun change to miliaun * rm paramenter inside super * add more 'miliaun','biliaun','triliaun' * up to -1234567 * up to 2345.75 * remove parameter inside super * changed e to resin * changed o to u * implemented test cardinal float * add test ordinal * changed antes de Cristo to antes Kristu * changed format * add 145254635102 testing * add test currency integer * add test currency integer negative * add test currency float * add test year negative * add test currency float negative * rm skip * changed zero to mamuk * changed EUR to USD * Currency fixes * replace walu to ualu * Tetun ordinal numbers * add new source code for to_cardinal tet * add ordinal to tetun * add da and k * fixed ordinal number for tetun language * changed variavel to english * fixed logic for ordinal number * Fix test_currency_float * Don;t show sentavus if no sentavus * test currency integer negative * add test for ordinal * fix test currency float negative * fixed test currency integer * rm the comment * fixed atus ida resin ida to atus ida ida * add DRY * add test * add ho * tyup the source code * tyup source code * fixed ho bug * mv self.ho_result * changed 2 to 1 * fixed bug ho * pass the testing * Flake8 fix lang_TET.py * fix the test tet flake8 * isort test num2words * First small increases in coverage of TET * flake8 removing unused import * removed lines that doesn't execute test * removed anos line of code * removed unuse codes * Remove unused code in to_ordinal * assert raises ordinal tests * Remove if statement that was always true * rm the code * rm assert int(value) * fixed the failing error * Remove unicode literals and division * fixed the error * remove empty line --------- Co-authored-by: onorio Co-authored-by: Mariano de Deus Co-authored-by: Mario Co-authored-by: joanico Co-authored-by: MarioAP --- README.rst | 1 + num2words/__init__.py | 5 +- num2words/lang_TET.py | 251 ++++++++++++++++++++ tests/test_tet.py | 541 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 796 insertions(+), 2 deletions(-) create mode 100644 num2words/lang_TET.py create mode 100644 tests/test_tet.py diff --git a/README.rst b/README.rst index 9b1e97f6..3c6cd289 100644 --- a/README.rst +++ b/README.rst @@ -121,6 +121,7 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``ro`` (Romanian) * ``ru`` (Russian) * ``te`` (Telugu) +* ``tet`` (Tetum) * ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) diff --git a/num2words/__init__.py b/num2words/__init__.py index 43616cce..6b39b4f4 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -24,8 +24,8 @@ lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, - lang_TH, lang_TR, lang_UK, lang_VI) + 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(), @@ -80,6 +80,7 @@ 'nl': lang_NL.Num2Word_NL(), '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(), } 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/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º') From 8c712e9ab5130ae58512a299b6294d56b3e3756f Mon Sep 17 00:00:00 2001 From: SkiBY Date: Wed, 2 Oct 2024 17:21:37 +0200 Subject: [PATCH 332/340] [FIX] ISO code for Belarusian language is be, not by. + coverage (#574) + improvements in big numbers + PLN currency added +reformat flake8 --- README.rst | 2 +- num2words/__init__.py | 4 +- num2words/{lang_BY.py => lang_BE.py} | 48 +++--- num2words/lang_EU.py | 2 +- tests/{test_by.py => test_be.py} | 216 ++++++++++++++++----------- 5 files changed, 166 insertions(+), 106 deletions(-) rename num2words/{lang_BY.py => lang_BE.py} (89%) rename tests/{test_by.py => test_be.py} (61%) diff --git a/README.rst b/README.rst index 3c6cd289..c207324d 100644 --- a/README.rst +++ b/README.rst @@ -79,7 +79,7 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``am`` (Amharic) * ``ar`` (Arabic) * ``az`` (Azerbaijani) -* ``by`` (Belarusian) +* ``be`` (Belarusian) * ``ce`` (Chechen) * ``cy`` (Welsh) * ``cz`` (Czech) diff --git a/num2words/__init__.py b/num2words/__init__.py index 6b39b4f4..c513d853 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BY, lang_CA, lang_CE, lang_CY, +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, @@ -31,7 +31,7 @@ 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), 'az': lang_AZ.Num2Word_AZ(), - 'by': lang_BY.Num2Word_BY(), + 'be': lang_BE.Num2Word_BE(), 'ca': lang_CA.Num2Word_CA(), 'ce': lang_CE.Num2Word_CE(), 'cy': lang_CY.Num2Word_CY(), diff --git a/num2words/lang_BY.py b/num2words/lang_BE.py similarity index 89% rename from num2words/lang_BY.py rename to num2words/lang_BE.py index ec825fd0..c41d6e4e 100644 --- a/num2words/lang_BY.py +++ b/num2words/lang_BE.py @@ -94,6 +94,17 @@ 9: "дзевяноста", } +TWENTIES_ORD = ( + ("дваццаць", "дваццаці"), + ("трыццаць", "трыццаці"), + ("сорак", "сарака"), + ("пяцьдзясят", "пяцідзясяці"), + ("шэсцьдзясят", "шaсцідзясяці"), + ("семдзесят", "сямідзесяці"), + ("восемдзесят", "васьмідзесяці"), + ("дзевяноста", "дзевяноста"), +) + HUNDREDS = { 1: "сто", 2: "дзвесце", @@ -120,7 +131,7 @@ } -class Num2Word_BY(Num2Word_Base): +class Num2Word_BE(Num2Word_Base): CURRENCY_FORMS = { "RUB": ( ("расійскі рубель", "расійскія рублі", "расійскіх рублёў"), @@ -138,6 +149,7 @@ class Num2Word_BY(Num2Word_Base): ("капейка", "капейкі", "капеек"), ), "UZS": (("сум", "сумы", "сумаў"), ("тыйін", "тыйіны", "тыйінаў")), + "PLN": (("злоты", "злотых", "злотых"), ("грош", "грошы", "грошаў")), } def setup(self): @@ -204,6 +216,8 @@ def pluralize(self, n, forms): 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: @@ -223,8 +237,6 @@ def to_ordinal(self, number, gender="m"): lastword = ( self.ords_adjective.get(lastword[:-3], lastword) + "соты" ) - elif lastword[-5:] == "шэсць": - lastword = "шосты" elif lastword[-7:] == "дзесяць": lastword = "дзясяты" elif lastword[-9:] == "семдзесят": @@ -242,6 +254,8 @@ def to_ordinal(self, number, gender="m"): 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] + "ны" @@ -254,9 +268,7 @@ def to_ordinal(self, number, gender="m"): lastword = lastword[:-1] + "ая" if gender == "n": - if lastword[-2:] in [ - "ці", "ца" - ]: + if lastword[-2:] in ["ці", "ца"]: lastword = lastword[:-2] + "цяе" else: lastword = lastword[:-1] + "ае" @@ -266,16 +278,20 @@ def to_ordinal(self, number, gender="m"): outwords[-2] = outwords[-1] del outwords[-1] - if len(outwords) > 2 and "тысяч" in outwords[-1]: - if 'сорак' in outwords[-3]: - outwords[-3] = outwords[-3].replace('сорак', 'сарака') - outwords[-3] = outwords[-3] + outwords[-2] + outwords[-1] - del 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)] - elif len(outwords) > 1 and "тысяч" in outwords[-1]: - outwords[-2] = outwords[-2] + outwords[-1] - del outwords[-1] return " ".join(outwords).strip() def _money_verbose(self, number, currency): @@ -294,8 +310,6 @@ def _cents_verbose(self, number, currency): return self._int2word(number, gender) def _int2word(self, n, gender="m"): - if isinstance(gender, bool) and gender: - gender = "f" if n < 0: return " ".join([self.negword, self._int2word(abs(n), gender)]) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 7c07bb56..0ff74ab2 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -53,7 +53,7 @@ class Num2Word_EU(Num2Word_Base): CURRENCY_ADJECTIVES = { 'AUD': 'Australian', - 'BYN': 'Belarussian', + 'BYN': 'Belarusian', 'CAD': 'Canadian', 'EEK': 'Estonian', 'USD': 'US', diff --git a/tests/test_by.py b/tests/test_be.py similarity index 61% rename from tests/test_by.py rename to tests/test_be.py index 087c0c11..c674e98b 100644 --- a/tests/test_by.py +++ b/tests/test_be.py @@ -25,25 +25,25 @@ class Num2WordsBYTest(TestCase): def test_cardinal(self): - self.assertEqual(num2words(100, lang="by"), "сто") - self.assertEqual(num2words(101, lang="by"), "сто адзін") - self.assertEqual(num2words(110, lang="by"), "сто дзесяць") - self.assertEqual(num2words(115, lang="by"), "сто пятнаццаць") - self.assertEqual(num2words(123, lang="by"), "сто дваццаць тры") - self.assertEqual(num2words(1000, lang="by"), "адна тысяча") - self.assertEqual(num2words(1001, lang="by"), "адна тысяча адзін") - self.assertEqual(num2words(2012, lang="by"), "дзве тысячы дванаццаць") - self.assertEqual( - num2words(12519.85, lang="by"), + 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="by"), + num2words(1234567890, lang="be"), "адзін мільярд дзвесце трыццаць чатыры мільёны пяцьсот " "шэсцьдзясят сем тысяч восемсот дзевяноста", ) self.assertEqual( - num2words(461407892039002157189883901676, lang="by"), + num2words(461407892039002157189883901676, lang="be"), "чатырыста шэсцьдзясят адзін " "актыльён чатырыста сем сэптыльёнаў восемсот дзевяноста " "два секстыльёны трыццаць дзевяць квінтыльёнаў два квадрыльёны " @@ -52,7 +52,7 @@ def test_cardinal(self): "шэсцьсот семдзесят шэсць", ) self.assertEqual( - num2words(94234693663034822824384220291, lang="by"), + num2words(94234693663034822824384220291, lang="be"), "дзевяноста чатыры актыльёны " "дзвесце трыццаць чатыры сэптыльёны шэсцьсот дзевяноста тры " "секстыльёны шэсцьсот шэсцьдзясят тры квінтыльёны трыццаць " @@ -60,250 +60,280 @@ def test_cardinal(self): "дваццаць чатыры мільярды трыста восемдзесят чатыры мільёны " "дзвесце дваццаць тысяч дзвесце дзевяноста адзін", ) - self.assertEqual(num2words(5, lang="by"), "пяць") - self.assertEqual(num2words(15, lang="by"), "пятнаццаць") - self.assertEqual(num2words(154, lang="by"), "сто пяцьдзясят чатыры") + self.assertEqual(num2words(5, lang="be"), "пяць") + self.assertEqual(num2words(15, lang="be"), "пятнаццаць") + self.assertEqual(num2words(154, lang="be"), "сто пяцьдзясят чатыры") self.assertEqual( - num2words(1135, lang="by"), "адна тысяча сто трыццаць пяць" + num2words(1135, lang="be"), "адна тысяча сто трыццаць пяць" ) self.assertEqual( - num2words(418531, lang="by"), + num2words(418531, lang="be"), "чатырыста васямнаццаць тысяч пяцьсот трыццаць адзін", ) self.assertEqual( - num2words(1000139, lang="by"), "адзін мільён сто трыццаць дзевяць" + num2words(1000139, lang="be"), "адзін мільён сто трыццаць дзевяць" ) - self.assertEqual(num2words(-1, lang="by"), "мінус адзін") - self.assertEqual(num2words(-15, lang="by"), "мінус пятнаццаць") - self.assertEqual(num2words(-100, lang="by"), "мінус сто") + 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="by"), "пяць коска два") - self.assertEqual(num2words(10.02, lang="by"), "дзесяць коска нуль два") + self.assertEqual(num2words(5.2, lang="be"), "пяць коска два") + self.assertEqual(num2words(10.02, lang="be"), "дзесяць коска нуль два") self.assertEqual( - num2words(15.007, lang="by"), "пятнаццаць коска нуль нуль сем" + num2words(15.007, lang="be"), "пятнаццаць коска нуль нуль сем" ) self.assertEqual( - num2words(561.42, lang="by"), + num2words(561.42, lang="be"), "пяцьсот шэсцьдзясят адзін коска сорак два", ) self.assertEqual( - num2words(561.0, lang="by"), "пяцьсот шэсцьдзясят адзін коска нуль" + num2words(561.0, lang="be"), "пяцьсот шэсцьдзясят адзін коска нуль" ) def test_to_ordinal(self): - self.assertEqual(num2words(1, lang="by", to="ordinal"), "першы") - self.assertEqual(num2words(5, lang="by", to="ordinal"), "пяты") - self.assertEqual(num2words(6, lang="by", to="ordinal"), "шосты") - self.assertEqual(num2words(10, lang="by", to="ordinal"), "дзясяты") + 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="by", to="ordinal"), "трынаццаты") - self.assertEqual(num2words(20, lang="by", to="ordinal"), "дваццаты") + self.assertEqual(num2words(13, lang="be", to="ordinal"), "трынаццаты") + self.assertEqual(num2words(20, lang="be", to="ordinal"), "дваццаты") self.assertEqual( - num2words(23, lang="by", to="ordinal"), "дваццаць трэці" + num2words(23, lang="be", to="ordinal"), "дваццаць трэці" ) self.assertEqual( - num2words(23, lang="by", to="ordinal", gender="f"), + num2words(23, lang="be", to="ordinal", gender="f"), "дваццаць трэцяя", ) self.assertEqual( - num2words(23, lang="by", to="ordinal", gender="n"), + num2words(23, lang="be", to="ordinal", gender=True), + "дваццаць трэцяя", + ) + self.assertEqual( + num2words(23, lang="be", to="ordinal", gender="n"), "дваццаць трэцяе", ) - self.assertEqual(num2words(40, lang="by", to="ordinal"), "саракавы") self.assertEqual( - num2words(61, lang="by", to="ordinal"), "шэсцьдзясят першы" + 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(70, lang="by", to="ordinal"), "сямідзясяты") - self.assertEqual(num2words(100, lang="by", to="ordinal"), "соты") + self.assertEqual(num2words(500, lang="be", to="ordinal"), "пяцісоты") + self.assertEqual( - num2words(136, lang="by", to="ordinal"), "сто трыццаць шосты" + num2words(500, lang="be", to="ordinal", gender="f"), "пяцісотая" ) - self.assertEqual(num2words(500, lang="by", to="ordinal"), "пяцісоты") self.assertEqual( - num2words(500, lang="by", to="ordinal", gender="f"), "пяцісотая" + num2words(500, lang="be", to="ordinal", gender="n"), "пяцісотае" ) + self.assertEqual(num2words(1000, lang="be", to="ordinal"), "тысячны") + self.assertEqual( - num2words(500, lang="by", to="ordinal", gender="n"), "пяцісотае" + num2words(1000, lang="be", to="ordinal", gender="f"), "тысячная" ) - self.assertEqual(num2words(1000, lang="by", to="ordinal"), "тысячны") + self.assertEqual( + num2words(1000, lang="be", to="ordinal", gender="n"), "тысячнае" + ) self.assertEqual( - num2words(1000, lang="by", to="ordinal", gender="f"), "тысячная" + 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(1000, lang="by", to="ordinal", gender="n"), "тысячнае" + num2words(75000, lang="be", to="ordinal"), "сямідзесяціпяцітысячны" ) self.assertEqual( - num2words(1001, lang="by", to="ordinal"), "тысяча першы" + num2words(1000000, lang="be", to="ordinal"), "мільённы" ) self.assertEqual( - num2words(2000, lang="by", to="ordinal"), "двухтысячны" + num2words(30000000, lang="be", to="ordinal"), "трыццацімільённы" ) self.assertEqual( - num2words(10000, lang="by", to="ordinal"), "дзесяцітысячны" + num2words(1000000000, lang="be", to="ordinal"), "мільярдны" ) self.assertEqual( - num2words(42000, lang="by", to="ordinal"), "саракадвухтысячны" + num2words(3000000000, lang="be", to="ordinal"), "трохмільярдны" ) self.assertEqual( - num2words(1000000, lang="by", to="ordinal"), "мільённы" + num2words(43000000000, lang="be", to="ordinal"), + "саракатрохмільярдны", ) self.assertEqual( - num2words(1000000000, lang="by", to="ordinal"), "мільярдны" + num2words(333000000000, lang="be", to="ordinal"), + "трыстатрыццацітрохмільярдны", ) def test_to_currency(self): self.assertEqual( - num2words(1.0, lang="by", to="currency", currency="EUR"), + num2words(1.0, lang="be", to="currency", currency="EUR"), "адзін еўра, нуль цэнтаў", ) self.assertEqual( - num2words(1.0, lang="by", to="currency", currency="RUB"), + num2words(1.0, lang="be", to="currency", currency="RUB"), "адзін расійскі рубель, нуль капеек", ) self.assertEqual( - num2words(1.0, lang="by", to="currency", currency="BYN"), + num2words(1.0, lang="be", to="currency", currency="BYN"), "адзін беларускі рубель, нуль капеек", ) self.assertEqual( - num2words(1.0, lang="by", to="currency", currency="UAH"), + num2words(1.0, lang="be", to="currency", currency="UAH"), "адна грыўна, нуль капеек", ) self.assertEqual( - num2words(1234.56, lang="by", to="currency", currency="EUR"), + num2words(1234.56, lang="be", to="currency", currency="EUR"), "адна тысяча дзвесце трыццаць чатыры еўра, " "пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words(1234.56, lang="by", to="currency", currency="RUB"), + num2words(1234.56, lang="be", to="currency", currency="RUB"), "адна тысяча дзвесце трыццаць чатыры расійскія рублі, " "пяцьдзясят шэсць капеек", ) self.assertEqual( - num2words(1234.56, lang="by", to="currency", currency="BYN"), + num2words(1234.56, lang="be", to="currency", currency="BYN"), "адна тысяча дзвесце трыццаць чатыры беларускія рублі, " "пяцьдзясят шэсць капеек", ) self.assertEqual( - num2words(1234.56, lang="by", to="currency", currency="UAH"), + num2words(1234.56, lang="be", to="currency", currency="UAH"), "адна тысяча дзвесце трыццаць чатыры грыўны, " "пяцьдзясят шэсць капеек", ) self.assertEqual( num2words( - 10111, lang="by", to="currency", currency="EUR", separator=" і" + 10111, lang="be", to="currency", currency="EUR", separator=" і" ), "сто адзін еўра і адзінаццаць цэнтаў", ) self.assertEqual( num2words( - 10111, lang="by", to="currency", currency="RUB", separator=" і" + 10111, lang="be", to="currency", currency="RUB", separator=" і" ), "сто адзін расійскі рубель і адзінаццаць капеек", ) self.assertEqual( num2words( - 10111, lang="by", to="currency", currency="BYN", separator=" і" + 10111, lang="be", to="currency", currency="BYN", separator=" і" ), "сто адзін беларускі рубель і адзінаццаць капеек", ) self.assertEqual( num2words( - 10111, lang="by", to="currency", currency="UAH", separator=" і" + 10111, lang="be", to="currency", currency="UAH", separator=" і" ), "сто адна грыўна і адзінаццаць капеек", ) self.assertEqual( num2words( - 10121, lang="by", to="currency", currency="EUR", separator=" і" + 10121, lang="be", to="currency", currency="EUR", separator=" і" ), "сто адзін еўра і дваццаць адзін цэнт", ) self.assertEqual( num2words( - 10121, lang="by", to="currency", currency="RUB", separator=" і" + 10121, lang="be", to="currency", currency="RUB", separator=" і" ), "сто адзін расійскі рубель і дваццаць адна капейка", ) self.assertEqual( num2words( - 10121, lang="by", to="currency", currency="BYN", separator=" і" + 10121, lang="be", to="currency", currency="BYN", separator=" і" ), "сто адзін беларускі рубель і дваццаць адна капейка", ) self.assertEqual( num2words( - 10121, lang="by", to="currency", currency="UAH", separator=" і" + 10121, lang="be", to="currency", currency="UAH", separator=" і" ), "сто адна грыўна і дваццаць адна капейка", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="EUR", separator=" і" + 10122, lang="be", to="currency", currency="EUR", separator=" і" ), "сто адзін еўра і дваццаць два цэнты", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="RUB", separator=" і" + 10122, lang="be", to="currency", currency="RUB", separator=" і" ), "сто адзін расійскі рубель і дваццаць дзве капейкі", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="BYN", separator=" і" + 10122, lang="be", to="currency", currency="BYN", separator=" і" ), "сто адзін беларускі рубель і дваццаць дзве капейкі", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="UAH", separator=" і" + 10122, lang="be", to="currency", currency="UAH", separator=" і" ), "сто адна грыўна і дваццаць дзве капейкі", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="KZT", separator=" і" + 10122, lang="be", to="currency", currency="KZT", separator=" і" ), "сто адзін тэнге і дваццаць два тыйіны", ) self.assertEqual( num2words( - -1251985, lang="by", to="currency", currency="EUR", cents=False + -1251985, lang="be", to="currency", currency="EUR", cents=False ), "мінус дванаццаць тысяч пяцьсот дзевятнаццаць еўра, 85 цэнтаў", ) self.assertEqual( num2words( - -1251985, lang="by", to="currency", currency="RUB", cents=False + -1251985, lang="be", to="currency", currency="RUB", cents=False ), "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " "расійскіх рублёў, 85 капеек", ) self.assertEqual( num2words( - -1251985, lang="by", to="currency", currency="BYN", cents=False + -1251985, lang="be", to="currency", currency="BYN", cents=False ), "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " "беларускіх рублёў, 85 капеек", ) self.assertEqual( num2words( - -1251985, lang="by", to="currency", currency="UAH", cents=False + -1251985, lang="be", to="currency", currency="UAH", cents=False ), "мінус дванаццаць тысяч пяцьсот дзевятнаццаць грыўнаў, 85 капеек", ) self.assertEqual( num2words( "38.4", - lang="by", + lang="be", to="currency", separator=" і", cents=False, @@ -314,7 +344,7 @@ def test_to_currency(self): self.assertEqual( num2words( "38.4", - lang="by", + lang="be", to="currency", separator=" і", cents=False, @@ -325,7 +355,7 @@ def test_to_currency(self): self.assertEqual( num2words( "38.4", - lang="by", + lang="be", to="currency", separator=" і", cents=False, @@ -334,22 +364,38 @@ def test_to_currency(self): "трыццаць восем грыўнаў і 40 капеек", ) self.assertEqual( - num2words("1230.56", lang="by", to="currency", currency="USD"), + num2words("1230.56", lang="be", to="currency", currency="USD"), "адна тысяча дзвесце трыццаць долараў, пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words("1231.56", lang="by", to="currency", currency="USD"), + num2words("1231.56", lang="be", to="currency", currency="USD"), "адна тысяча дзвесце трыццаць адзін долар, " "пяцьдзясят шэсць цэнтаў", ) self.assertEqual( - num2words("1234.56", lang="by", to="currency", currency="USD"), + num2words("1234.56", lang="be", to="currency", currency="USD"), "адна тысяча дзвесце трыццаць чатыры долары, пяцьдзясят шэсць " "цэнтаў", ) self.assertEqual( num2words( - 10122, lang="by", to="currency", currency="UZS", separator=" і" + 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"), + "дзевяць тысяч дзевяцьсот дзевяноста дзевяць злотых, " + "трыццаць дзевяць грошаў", + ) From 2ab2667e37e7b617d5b8b51bb99a2f9d49b5685c Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:22:49 -0500 Subject: [PATCH 333/340] Add test to improve coverage (#595) Co-authored-by: Marlon Rodriguez Garcia --- tests/test_base.py | 24 ++++++++++++++++++++++++ tests/test_dk.py | 8 ++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index efa1bc81..c9abe14d 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -62,3 +62,27 @@ def test_is_title(self): self.base.title("one"), "one" ) + + def test_set_high_numwords_not_implemented(self): + with self.assertRaises(NotImplementedError): + self.base.set_high_numwords() + + def test_to_ordinal_num(self): + from num2words.base import Num2Word_Base + self.base = Num2Word_Base() + self.assertEqual( + self.base.to_ordinal_num(1), + 1 + ) + self.assertEqual( + self.base.to_ordinal_num(100), + 100 + ) + self.assertEqual( + self.base.to_ordinal_num(1000), + 1000 + ) + + def test_pluralize_not_implemented(self): + with self.assertRaises(NotImplementedError): + self.base.pluralize(n=None, forms=None) diff --git a/tests/test_dk.py b/tests/test_dk.py index 889e9d8e..4c2e6ce3 100644 --- a/tests/test_dk.py +++ b/tests/test_dk.py @@ -20,6 +20,7 @@ from unittest import TestCase from num2words import num2words +from num2words.lang_DK import Num2Word_DK class Num2WordsDKTest(TestCase): @@ -35,3 +36,10 @@ def test_cardinal(self): 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") + + def test_to_ordinal_num(self): + num2words_dk = Num2Word_DK() + self.assertEqual(num2words_dk.to_ordinal_num(1), "1te") + self.assertEqual(num2words_dk.to_ordinal_num(2), "2en") + self.assertEqual(num2words_dk.to_ordinal_num(5), "5te") + self.assertEqual(num2words_dk.to_ordinal_num(10), "10ende") From f503d8c4ef83003ea6eaaeeab62166762fc69b5a Mon Sep 17 00:00:00 2001 From: Matrosdzmehedi Date: Wed, 20 Nov 2024 03:29:54 +0600 Subject: [PATCH 334/340] Added Bangla language support to num2word for Bangladesh. (#589) * Feature:bangla number to word conversion library. * bangla number to word conversion library resgister to num2word converter class. * Test case for bangla number to word conversion. * refactor and rename class for library compatibility. * fix: isort and flake8 formating issue. * fix: add more test to increase coverage. --------- Co-authored-by: Mehedi Hasan Khondoker Co-authored-by: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> --- README.rst | 1 + num2words/__init__.py | 19 +-- num2words/lang_BN.py | 203 +++++++++++++++++++++++ tests/test_bn.py | 365 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 579 insertions(+), 9 deletions(-) create mode 100644 num2words/lang_BN.py create mode 100644 tests/test_bn.py diff --git a/README.rst b/README.rst index c207324d..e1aa8e5e 100644 --- a/README.rst +++ b/README.rst @@ -80,6 +80,7 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``ar`` (Arabic) * ``az`` (Azerbaijani) * ``be`` (Belarusian) +* ``bn`` (Bangladeshi) * ``ce`` (Chechen) * ``cy`` (Welsh) * ``cz`` (Czech) diff --git a/num2words/__init__.py b/num2words/__init__.py index c513d853..da0eceea 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,21 +17,22 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_CA, lang_CE, lang_CY, - lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EN_NG, - lang_EO, lang_ES, lang_ES_CO, lang_ES_CR, lang_ES_GT, - lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, - lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, lang_IS, - lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, - lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, - lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE, lang_TET, - lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_BN, lang_CA, lang_CE, + lang_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(), + 'bn': lang_BN.Num2Word_BN(), 'ca': lang_CA.Num2Word_CA(), 'ce': lang_CE.Num2Word_CE(), 'cy': lang_CY.Num2Word_CY(), diff --git a/num2words/lang_BN.py b/num2words/lang_BN.py new file mode 100644 index 00000000..ef86ed71 --- /dev/null +++ b/num2words/lang_BN.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Author: Mehedi Hasan Khondoker +# Email: mehedihasankhondoker [at] gmail.com +# Copyright (c) 2024, Mehedi Hasan Khondoker. All Rights Reserved. + +# This library is build for Bangladesh format Number to Word conversion. +# You are welcome as contributor to the library. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + + +from decimal import Decimal + +RANKING = ['', 'প্রথম', 'দ্বিতীয়', 'তৃতীয়', 'চতুর্থ', 'পঞ্চম', 'ষষ্ঠ', + 'সপ্তম', 'অষ্টম', 'নবম', 'দশম'] # pragma: no cover + +AKOK = ['', 'এক', 'দুই', 'তিন', 'চার', 'পাঁচ', 'ছয়', + 'সাত', 'আট', 'নয়'] # pragma: no cover + +DOSOK = [ + 'দশ', 'এগারো', 'বারো', 'তেরো', 'চৌদ্দ', 'পনের', + 'ষোল', 'সতের', 'আঠারো', 'উনিশ', + 'বিশ', 'একুশ', 'বাইশ', 'তেইশ', 'চব্বিশ', 'পঁচিশ', + 'ছাব্বিশ', 'সাতাশ', 'আটাশ', 'উনত্রিশ', + 'ত্রিশ', 'একত্রিশ', 'বত্রিশ', 'তেত্রিশ', 'চৌত্রিশ', 'পঁইত্রিশ', + 'ছত্রিশ', 'সাতত্রিশ', 'আটত্রিশ', 'উনচল্লিশ', 'চল্লিশ', + 'একচল্লিশ', 'বিয়াল্লিশ', 'তেতাল্লিশ', 'চৌচল্লিশ', + 'পঁয়তাল্লিশ', 'ছেচল্লিশ', 'সাতচল্লিশ', 'আটচল্লিশ', 'উনপঞ্চাশ', + 'পঞ্চাশ', 'একান্ন', 'বাহান্ন', 'তিপ্পান্ন', 'চুয়ান্ন', 'পঞ্চান্ন', + 'ছাপ্পান্ন', 'সাতান্ন', 'আটান্ন', 'উনষাট', 'ষাট', + 'একষট্টি', 'বাষট্টি', 'তেষট্টি', 'চৌষট্টি', 'পঁয়ষট্টি', + 'ছিষট্টি', 'সাতষট্টি', 'আটষট্টি', 'উনসত্তর', 'সত্তর', + 'একাত্তর ', 'বাহাত্তর', 'তিয়াত্তর', 'চুয়াত্তর', 'পঁচাত্তর', + 'ছিয়াত্তর', 'সাতাত্তর', 'আটাত্তর', 'উনআশি', 'আশি', + 'একাশি', 'বিরাশি', 'তিরাশি', 'চুরাশি', 'পঁচাশি', + 'ছিয়াশি', 'সাতাশি', 'আটাশি', 'উননব্বই', 'নব্বই', + 'একানব্বই', 'বিরানব্বই', 'তিরানব্বই', 'চুরানব্বই', 'পঁচানব্বই', + 'ছিয়ানব্বই', 'সাতানব্বই', 'আটানব্বই', 'নিরানব্বই' +] # pragma: no cover +HAZAR = ' হাজার ' # pragma: no cover +LAKH = ' লাখ ' # pragma: no cover +KOTI = ' কোটি ' # pragma: no cover +MAX_NUMBER = 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 # noqa: E501 # pragma: no cover + + +class NumberTooLargeError(Exception): + """Custom exception for numbers that are too large.""" + pass + + +class Num2Word_BN: + + @staticmethod + def str_to_number(number): + return abs(Decimal(str(number))) # pragma: no cover + + @staticmethod + def parse_number(number: Decimal): + dosomik = str(number - int(number)).split('.')[1:] + dosomik_str = ''.join(dosomik) if dosomik else 0 + return int(number), int(dosomik_str) + + @staticmethod + def parse_paisa(number: Decimal): + # 1-99 for paisa count so two digits are valid. + paisa = str(number - int(number)).split('.')[1:] + paisa_str = ''.join(paisa) if paisa else 0 + + # this is need, when we parse to decimal it removes trailing 0 . + if paisa_str: + paisa_str = str(int(paisa_str) * 100)[:2] + return int(number), int(paisa_str) + + def _is_smaller_than_max_number(self, number): + if MAX_NUMBER >= number: + return True + raise NumberTooLargeError(f'Too Large number maximum ' + f'value={MAX_NUMBER}') + + def _dosomik_to_bengali_word(self, number): + word = '' + for i in str(number): + word += ' ' + AKOK[int(i)] + return word + + def _number_to_bengali_word(self, number): + if number == 0: + return 'শূন্য' + + words = '' + + if number >= 10 ** 7: + words += self._number_to_bengali_word(number // 10 ** 7) + KOTI + number %= 10 ** 7 + + if number >= 10 ** 5: + words += self._number_to_bengali_word(number // 10 ** 5) + LAKH + number %= 10 ** 5 + + if number >= 1000: + words += self._number_to_bengali_word(number // 1000) + HAZAR + number %= 1000 + + if number >= 100: + words += AKOK[number // 100] + 'শত ' + number %= 100 + + if 10 <= number <= 99: + words += DOSOK[number - 10] + ' ' + number = 0 + + if 0 < number < 10: + words += AKOK[number] + ' ' + + return words.strip() + + def to_currency(self, val): + """ + This function represent a number to word in bangla taka and paisa. + example: + 1 = এক টাকা, + 101 = একশত এক টাকা, + 9999.15 = নয় হাজার নয়শত নিরানব্বই টাকা পনের পয়সা + and so on. + """ + + dosomik_word = None + number = self.str_to_number(val) + number, decimal_part = self.parse_paisa(number) + self._is_smaller_than_max_number(number) + + if decimal_part > 0: + dosomik_word = f' {self._number_to_bengali_word(decimal_part)} পয়সা' # noqa: E501 + + words = f'{self._number_to_bengali_word(number)} টাকা' + + if dosomik_word: + return (words + dosomik_word).strip() + return words.strip() + + def to_cardinal(self, number): + """ + This function represent a number to word in bangla. + example: + 1 = এক, + 101 = একশত এক, + 9999 = নয় হাজার নয়শত নিরানব্বই + and so on. + """ + + dosomik_word = None + number = self.str_to_number(number) + number, decimal_part = self.parse_number(number) + self._is_smaller_than_max_number(number) + + if decimal_part > 0: + dosomik_word = f' দশমিক{self._dosomik_to_bengali_word(decimal_part)}' # noqa: E501 + + words = self._number_to_bengali_word(number) + + if dosomik_word: + return (words + dosomik_word).strip() + return words.strip() + + def to_ordinal(self, number): + return self.to_cardinal(number) + + def to_ordinal_num(self, number): + """ + This function represent a number to ranking in bangla. + example: + 1 = প্রথম, + 2 = দ্বিতীয়, + 1001 = এক হাজার একতম + and so on. + """ + self._is_smaller_than_max_number(number) + + if number in range(1, 11): + return RANKING[number] + else: + rank = self.to_cardinal(int(abs(number))) + if rank.endswith('ত'): + return rank + 'ম' + return rank + 'তম' + + def to_year(self, number): + """ + This function represent a number to year in bangla. + example: + 2002 = দুই হাজার দুই সাল, + 2024 = দুই হাজার চব্বিশ সাল + and so on. + """ + self._is_smaller_than_max_number(number) + return self.to_cardinal(int(abs(number))) + ' সাল' diff --git a/tests/test_bn.py b/tests/test_bn.py new file mode 100644 index 00000000..9147916c --- /dev/null +++ b/tests/test_bn.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Author: Mehedi Hasan Khondoker +# Email: mehedihasankhondoker [at] gmail.com +# Copyright (c) 2024, Mehedi Hasan Khondoker. All Rights Reserved. + +# This library is build for Bangladesh format Number to Word conversion. +# You are welcome as contributor to the library. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +from __future__ import unicode_literals + +from decimal import Decimal +from unittest import TestCase + +from num2words import num2words +from num2words.lang_BN import Num2Word_BN, NumberTooLargeError + + +class Num2WordsBNTest(TestCase): + maxDiff = None + + def test_negative(self): + self.assertEqual(num2words(-1, lang="bn"), u'এক') + + def test_0(self): + self.assertEqual(num2words(0, lang="bn"), u'শূন্য') + + def test_1_to_10(self): + self.assertEqual(num2words(1, lang="bn"), u'এক') + self.assertEqual(num2words(2, lang="bn"), u'দুই') + self.assertEqual(num2words(7, lang="bn"), u'সাত') + self.assertEqual(num2words(10, lang="bn"), u'দশ') + + def test_11_to_19(self): + self.assertEqual(num2words(11, lang="bn"), u'এগারো') + self.assertEqual(num2words(13, lang="bn"), u'তেরো') + self.assertEqual(num2words(15, lang="bn"), u'পনের') + self.assertEqual(num2words(16, lang="bn"), u'ষোল') + self.assertEqual(num2words(19, lang="bn"), u'উনিশ') + + def test_20_to_99(self): + self.assertEqual(num2words(20, lang="bn"), u'বিশ') + self.assertEqual(num2words(23, lang="bn"), u'তেইশ') + self.assertEqual(num2words(28, lang="bn"), u'আটাশ') + self.assertEqual(num2words(31, lang="bn"), u'একত্রিশ') + self.assertEqual(num2words(40, lang="bn"), u'চল্লিশ') + self.assertEqual(num2words(66, lang="bn"), u'ছিষট্টি') + self.assertEqual(num2words(92, lang="bn"), u'বিরানব্বই') + + def test_100_to_999(self): + self.assertEqual(num2words(100, lang="bn"), u'একশত') + self.assertEqual(num2words(111, lang="bn"), u'একশত এগারো') + self.assertEqual(num2words(150, lang="bn"), u'একশত পঞ্চাশ') + self.assertEqual(num2words(196, lang="bn"), u'একশত ছিয়ানব্বই') + self.assertEqual(num2words(200, lang="bn"), u'দুইশত') + self.assertEqual(num2words(210, lang="bn"), u'দুইশত দশ') + self.assertEqual(num2words(701, lang="bn"), u'সাতশত এক') + self.assertEqual(num2words(999, lang="bn"), u'নয়শত নিরানব্বই') + + def test_1000_to_9999(self): + self.assertEqual(num2words(1000, lang="bn"), u'এক হাজার') + self.assertEqual(num2words(1001, lang="bn"), u'এক হাজার এক') + self.assertEqual(num2words(1002, lang="bn"), u'এক হাজার দুই') + self.assertEqual(num2words(1010, lang="bn"), u'এক হাজার দশ') + self.assertEqual(num2words(1110, lang="bn"), u'এক হাজার একশত দশ') + self.assertEqual(num2words(1111, lang="bn"), u'এক হাজার একশত এগারো') + self.assertEqual(num2words(1500, lang="bn"), u'এক হাজার পাঁচশত') + self.assertEqual(num2words(2000, lang="bn"), u'দুই হাজার') + self.assertEqual(num2words(2042, lang="bn"), u'দুই হাজার বিয়াল্লিশ') + self.assertEqual(num2words(3000, lang="bn"), u'তিন হাজার') + self.assertEqual(num2words(3301, lang="bn"), u'তিন হাজার তিনশত এক') + self.assertEqual(num2words(3108, lang="bn"), u'তিন হাজার একশত আট') + self.assertEqual(num2words(6870, lang="bn"), u'ছয় হাজার আটশত সত্তর') + self.assertEqual(num2words(7378, lang="bn"), + u'সাত হাজার তিনশত আটাত্তর') + self.assertEqual(num2words(9999, lang="bn"), + u'নয় হাজার নয়শত নিরানব্বই') + + def test_10000_to_99999(self): + self.assertEqual(num2words(10000, lang="bn"), + u'দশ হাজার') + self.assertEqual(num2words(10501, lang="bn"), + u'দশ হাজার পাঁচশত এক') + self.assertEqual(num2words(10999, lang="bn"), + u'দশ হাজার নয়শত নিরানব্বই') + self.assertEqual(num2words(13000, lang="bn"), u'তেরো হাজার') + self.assertEqual(num2words(15333, lang="bn"), + u'পনের হাজার তিনশত তেত্রিশ') + self.assertEqual(num2words(21111, lang="bn"), u'একুশ হাজার একশত এগারো') + self.assertEqual(num2words(21003, lang="bn"), u'একুশ হাজার তিন') + self.assertEqual(num2words(25020, lang="bn"), u'পঁচিশ হাজার বিশ') + self.assertEqual(num2words(68700, lang="bn"), + u'আটষট্টি হাজার সাতশত') + self.assertEqual(num2words(73781, lang="bn"), + u'তিয়াত্তর হাজার সাতশত একাশি') + self.assertEqual(num2words(99999, lang="bn"), + u'নিরানব্বই হাজার নয়শত নিরানব্বই') + + def test_100000_to_999999(self): + self.assertEqual(num2words(100000, lang="bn"), u'এক লাখ') + self.assertEqual(num2words('100000', lang="bn"), u'এক লাখ') + self.assertEqual(num2words(199999, lang="bn"), + u'এক লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') + self.assertEqual(num2words(110000, lang="bn"), u'এক লাখ দশ হাজার') + self.assertEqual(num2words(150010, lang="bn"), + u'এক লাখ পঞ্চাশ হাজার দশ') + self.assertEqual(num2words('200200', lang="bn"), u'দুই লাখ দুইশত') + self.assertEqual(num2words(737812, lang="bn"), + u'সাত লাখ সাতত্রিশ হাজার আটশত বারো') + self.assertEqual(num2words('999999', lang="bn"), + u'নয় লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') + + def test_1000000_to_9999999999999999(self): + self.assertEqual(num2words(1000000, lang="bn"), u'দশ লাখ') + self.assertEqual(num2words(20000000, lang="bn"), u'দুই কোটি') + self.assertEqual(num2words(300000000, lang="bn"), u'ত্রিশ কোটি') + self.assertEqual(num2words(4000000000, lang="bn"), u'চারশত কোটি') + self.assertEqual(num2words(50000000000, lang="bn"), u'পাঁচ হাজার কোটি') + self.assertEqual(num2words(600000000000, lang="bn"), u'ষাট হাজার কোটি') + self.assertEqual(num2words(7000000000000, lang="bn"), u'সাত লাখ কোটি') + self.assertEqual(num2words(80000000000000, lang="bn"), u'আশি লাখ কোটি') + self.assertEqual(num2words + (900000000000000, lang="bn"), u'নয় কোটি কোটি') + self.assertEqual(num2words(999999999999999, lang="bn"), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') # noqa: E501 + self.assertEqual(num2words(9999999999999999, lang="bn"), + u'নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') # noqa: E501 + + def test_dosomik_0_to_999999999999999999(self): + self.assertEqual(num2words(0.56, lang="bn"), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(num2words(1.11, lang="bn"), u'এক দশমিক এক এক') + self.assertEqual(num2words(2.66, lang="bn"), u'দুই দশমিক ছয় ছয়') + self.assertEqual(num2words(7.68, lang="bn"), u'সাত দশমিক ছয় আট') + self.assertEqual(num2words('10.35', lang="bn"), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(num2words('11.47', lang="bn"), u'এগারো দশমিক চার সাত') + self.assertEqual(num2words(13.69, lang="bn"), u'তেরো দশমিক ছয় নয়') + self.assertEqual(num2words(15.96, lang="bn"), u'পনের দশমিক নয় ছয়') + self.assertEqual(num2words(16.9999, lang="bn"), + u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(num2words(19.56587, lang="bn"), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(num2words(31.31, lang="bn"), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(num2words(40.85, lang="bn"), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(num2words(66.66, lang="bn"), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(num2words(92.978, lang="bn"), + u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(num2words(1000001.10, lang="bn"), + u'দশ লাখ এক দশমিক এক') + self.assertEqual(num2words(20000000.22, lang="bn"), + u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(num2words(300030000.33, lang="bn"), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(num2words('4004000444.44', lang="bn"), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(num2words(50000000001.50, lang="bn"), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(num2words(600000000600.66, lang="bn"), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(num2words(7000000000000.77, lang="bn"), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(num2words(80000000000888.88, lang="bn"), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(num2words(900000000000000.9, lang="bn"), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(num2words(999999999999999.9, lang="bn"), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(num2words(9999999999999999.99, lang="bn"), + u'একশত কোটি কোটি') + self.assertEqual(num2words(99999999999999999.99, lang="bn"), + u'এক হাজার কোটি কোটি') + self.assertEqual(num2words('999999999999999999.9', lang="bn"), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + + def test_to_currency(self): + n = Num2Word_BN() + self.assertEqual(n.to_currency(20.0), u'বিশ টাকা') + self.assertEqual(n.to_currency(20.50), u'বিশ টাকা পঞ্চাশ পয়সা') + self.assertEqual(n.to_currency(33.51), u'তেত্রিশ টাকা একান্ন পয়সা') + self.assertEqual(n.to_currency(99.99), + u'নিরানব্বই টাকা নিরানব্বই পয়সা') + self.assertEqual(n.to_currency(10000.1), + u'দশ হাজার টাকা দশ পয়সা') + self.assertEqual(n.to_currency(555555.50), + u'পাঁচ লাখ পঞ্চান্ন হাজার পাঁচশত পঞ্চান্ন টাকা পঞ্চাশ পয়সা') # noqa: E501 + self.assertEqual(n.to_currency(6666676), + u'ছিষট্টি লাখ ছিষট্টি হাজার ছয়শত ছিয়াত্তর টাকা') + self.assertEqual(n.to_currency(777777777), + u'সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত সাতাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(7777777778), + u'সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত আটাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(97777777778), + u'নয় হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত আটাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(977777777781), + u'সাতানব্বই হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত একাশি টাকা') # noqa: E501 + self.assertEqual(n.to_currency(9777777779781), + u'নয় লাখ সাতাত্তর হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ উনআশি হাজার সাতশত একাশি টাকা') # noqa: E501 + + def test_to_cardinal(self): + n = Num2Word_BN() + self.assertEqual(n.to_cardinal(0.56), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(n.to_cardinal(1.11), u'এক দশমিক এক এক') + self.assertEqual(n.to_cardinal(2.66), u'দুই দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(7.68), u'সাত দশমিক ছয় আট') + self.assertEqual(n.to_cardinal('10.35'), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(n.to_cardinal('11.47'), u'এগারো দশমিক চার সাত') + self.assertEqual(n.to_cardinal(13.69), u'তেরো দশমিক ছয় নয়') + self.assertEqual(n.to_cardinal(15.96), u'পনের দশমিক নয় ছয়') + self.assertEqual(n.to_cardinal(16.9999), u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(n.to_cardinal(19.56587), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(n.to_cardinal(31.31), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(n.to_cardinal(40.85), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(n.to_cardinal(66.66), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(92.978), u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(n.to_cardinal(1000001.10), u'দশ লাখ এক দশমিক এক') + self.assertEqual(n.to_cardinal(20000000.22), u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(n.to_cardinal(300030000.33), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(n.to_cardinal('4004000444.44'), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(n.to_cardinal(50000000001.50), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(n.to_cardinal(600000000600.66), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(7000000000000.77), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(n.to_cardinal(80000000000888.88), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(n.to_cardinal(900000000000000.9), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(n.to_cardinal(999999999999999.9), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(n.to_cardinal(9999999999999999.99), + u'একশত কোটি কোটি') + self.assertEqual(n.to_cardinal(99999999999999999.99), + u'এক হাজার কোটি কোটি') + self.assertEqual(n.to_cardinal('999999999999999999.99'), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয় নয়') # noqa: E501 + + def test_to_ordinal(self): + n = Num2Word_BN() + self.assertEqual(n.to_ordinal(0.56), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(n.to_ordinal(1.11), u'এক দশমিক এক এক') + self.assertEqual(n.to_ordinal(2.66), u'দুই দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(7.68), u'সাত দশমিক ছয় আট') + self.assertEqual(n.to_ordinal('10.35'), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(n.to_ordinal('11.47'), u'এগারো দশমিক চার সাত') + self.assertEqual(n.to_ordinal(13.69), u'তেরো দশমিক ছয় নয়') + self.assertEqual(n.to_ordinal(15.96), u'পনের দশমিক নয় ছয়') + self.assertEqual(n.to_ordinal(16.9999), u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(n.to_ordinal(19.56587), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(n.to_ordinal(31.31), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(n.to_ordinal(40.85), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(n.to_ordinal(66.66), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(92.978), u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(n.to_ordinal(1000001.10), u'দশ লাখ এক দশমিক এক') + self.assertEqual(n.to_ordinal(20000000.22), u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(n.to_ordinal(300030000.33), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(n.to_ordinal('4004000444.44'), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(n.to_ordinal(50000000001.50), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(n.to_ordinal(600000000600.66), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(7000000000000.77), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(n.to_ordinal(80000000000888.88), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(n.to_ordinal(900000000000000.9), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(n.to_ordinal(999999999999999.9), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(n.to_ordinal(9999999999999999.99), + u'একশত কোটি কোটি') + self.assertEqual(n.to_ordinal(99999999999999999.99), + u'এক হাজার কোটি কোটি') + self.assertEqual(n.to_ordinal('999999999999999999.99'), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয় নয়') # noqa: E501 + + def test_to_year(self): + n = Num2Word_BN() + self.assertEqual(n.to_year(1), u'এক সাল') + self.assertEqual(n.to_year(1000), u'এক হাজার সাল') + self.assertEqual(n.to_year(1500), u'এক হাজার পাঁচশত সাল') + self.assertEqual(n.to_year(1820), u'এক হাজার আটশত বিশ সাল') + self.assertEqual(n.to_year(1920), u'এক হাজার নয়শত বিশ সাল') + self.assertEqual(n.to_year(2024), u'দুই হাজার চব্বিশ সাল') + self.assertEqual(n.to_year(2004), u'দুই হাজার চার সাল') + + def test_to_ordinal_num(self): + n = Num2Word_BN() + self.assertEqual(n.to_ordinal_num(1), u'প্রথম') + self.assertEqual(n.to_ordinal_num(1000), u'এক হাজারতম') + self.assertEqual(n.to_ordinal_num(1500), u'এক হাজার পাঁচশতম') + self.assertEqual(n.to_ordinal_num(1820), u'এক হাজার আটশত বিশতম') + self.assertEqual(n.to_ordinal_num(1920), u'এক হাজার নয়শত বিশতম') + self.assertEqual(n.to_ordinal_num(2024), u'দুই হাজার চব্বিশতম') + self.assertEqual(n.to_ordinal_num(2004), u'দুই হাজার চারতম') + + def test_max_number_error(self): + n = Num2Word_BN() + + with self.assertRaises(NumberTooLargeError): + n.to_ordinal( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_cardinal( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_year( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_ordinal_num( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_currency( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + num2words( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991, # noqa: E501 + lang="bn") + + def test_is_smaller_than_max_number(self): + n = Num2Word_BN() + self.assertEqual(n._is_smaller_than_max_number(55555), True) + + def test_is_smaller_than_max_number_error(self): + with self.assertRaises(NumberTooLargeError): + n = Num2Word_BN() + n._is_smaller_than_max_number(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999) # noqa: E501 + + def test_parse_number(self): + n = Num2Word_BN() + self.assertEqual(n.parse_number(Decimal(3.25)), (3, 25)) + self.assertEqual(n.parse_number(Decimal(300.2550)), + (300, 2549999999999954525264911353588104248046875)) + + def test_parse_paisa(self): + n = Num2Word_BN() + self.assertEqual(n.parse_paisa(Decimal(3.25)), (3, 25)) + self.assertEqual(n.parse_paisa(300.2550), (300, 25)) + self.assertEqual(n.parse_paisa(100.5), (100, 50)) + + def test_number_to_bengali_word(self): + n = Num2Word_BN() + self.assertEqual(n._number_to_bengali_word(3), "তিন") + self.assertEqual(n._number_to_bengali_word(2550), + "দুই হাজার পাঁচশত পঞ্চাশ") + self.assertEqual(n._number_to_bengali_word(9999999999999999), + "নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই") # noqa: E501 From 0df2a0ebc91e9ffba7c978f69e418a3f7271eba2 Mon Sep 17 00:00:00 2001 From: Marek Madejski Date: Wed, 20 Nov 2024 17:36:21 +0100 Subject: [PATCH 335/340] Czech language ISO 639-1 code fix (#587) --- README.rst | 2 +- num2words/__init__.py | 4 +-- num2words/{lang_CZ.py => lang_CS.py} | 2 +- tests/{test_cz.py => test_cs.py} | 54 ++++++++++++++-------------- 4 files changed, 31 insertions(+), 31 deletions(-) rename num2words/{lang_CZ.py => lang_CS.py} (99%) rename tests/{test_cz.py => test_cs.py} (72%) diff --git a/README.rst b/README.rst index e1aa8e5e..16d33f59 100644 --- a/README.rst +++ b/README.rst @@ -82,8 +82,8 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``be`` (Belarusian) * ``bn`` (Bangladeshi) * ``ce`` (Chechen) +* ``cs`` (Czech) * ``cy`` (Welsh) -* ``cz`` (Czech) * ``de`` (German) * ``dk`` (Danish) * ``en_GB`` (English - Great Britain) diff --git a/num2words/__init__.py b/num2words/__init__.py index da0eceea..0c216ad2 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_BN, lang_CA, lang_CE, - lang_CY, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, + lang_CS, lang_CY, 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, @@ -35,8 +35,8 @@ 'bn': lang_BN.Num2Word_BN(), 'ca': lang_CA.Num2Word_CA(), 'ce': lang_CE.Num2Word_CE(), + 'cs': lang_CS.Num2Word_CS(), 'cy': lang_CY.Num2Word_CY(), - 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), 'en_NG': lang_EN_NG.Num2Word_EN_NG(), diff --git a/num2words/lang_CZ.py b/num2words/lang_CS.py similarity index 99% rename from num2words/lang_CZ.py rename to num2words/lang_CS.py index 04c44a07..6024b77d 100644 --- a/num2words/lang_CZ.py +++ b/num2words/lang_CS.py @@ -84,7 +84,7 @@ } -class Num2Word_CZ(Num2Word_Base): +class Num2Word_CS(Num2Word_Base): CURRENCY_FORMS = { 'CZK': ( ('koruna', 'koruny', 'korun'), ('halíř', 'halíře', 'haléřů') diff --git a/tests/test_cz.py b/tests/test_cs.py similarity index 72% rename from tests/test_cz.py rename to tests/test_cs.py index 1801e8f7..2c2b0e5f 100644 --- a/tests/test_cz.py +++ b/tests/test_cs.py @@ -22,39 +22,39 @@ from num2words import num2words -class Num2WordsCZTest(TestCase): +class Num2WordsCSTest(TestCase): def test_cardinal(self): - self.assertEqual(num2words(100, lang='cz'), "sto") - self.assertEqual(num2words(101, lang='cz'), "sto jedna") - self.assertEqual(num2words(110, lang='cz'), "sto deset") - self.assertEqual(num2words(115, lang='cz'), "sto patnáct") - self.assertEqual(num2words(123, lang='cz'), "sto dvacet tři") - self.assertEqual(num2words(1000, lang='cz'), "tisíc") - self.assertEqual(num2words(1001, lang='cz'), "tisíc jedna") - self.assertEqual(num2words(2012, lang='cz'), "dva tisíce dvanáct") - self.assertEqual( - num2words(10.02, lang='cz'), + self.assertEqual(num2words(100, lang='cs'), "sto") + self.assertEqual(num2words(101, lang='cs'), "sto jedna") + self.assertEqual(num2words(110, lang='cs'), "sto deset") + self.assertEqual(num2words(115, lang='cs'), "sto patnáct") + self.assertEqual(num2words(123, lang='cs'), "sto dvacet tři") + self.assertEqual(num2words(1000, lang='cs'), "tisíc") + self.assertEqual(num2words(1001, lang='cs'), "tisíc jedna") + self.assertEqual(num2words(2012, lang='cs'), "dva tisíce dvanáct") + self.assertEqual( + num2words(10.02, lang='cs'), "deset celá nula dva" ) self.assertEqual( - num2words(15.007, lang='cz'), + num2words(15.007, lang='cs'), "patnáct celá nula nula sedm" ) self.assertEqual( - num2words(12519.85, lang='cz'), + num2words(12519.85, lang='cs'), "dvanáct tisíc pětset devatenáct celá osmdesát pět" ) self.assertEqual( - num2words(123.50, lang='cz'), + num2words(123.50, lang='cs'), "sto dvacet tři celá pět" ) self.assertEqual( - num2words(1234567890, lang='cz'), + num2words(1234567890, lang='cs'), "miliarda dvěstě třicet čtyři miliony pětset šedesát " "sedm tisíc osmset devadesát" ) self.assertEqual( - num2words(215461407892039002157189883901676, lang='cz'), + num2words(215461407892039002157189883901676, lang='cs'), "dvěstě patnáct quintillionů čtyřista šedesát jedna kvadriliard " "čtyřista sedm kvadrilionů osmset devadesát dva triliardy třicet " "devět trilionů dva biliardy sto padesát sedm bilionů sto " @@ -62,7 +62,7 @@ def test_cardinal(self): "devětset jedna tisíc šestset sedmdesát šest" ) self.assertEqual( - num2words(719094234693663034822824384220291, lang='cz'), + num2words(719094234693663034822824384220291, lang='cs'), "sedmset devatenáct quintillionů devadesát " "čtyři kvadriliardy dvěstě třicet čtyři " "kvadriliony šestset devadesát tři triliardy " @@ -75,40 +75,40 @@ def test_cardinal(self): def test_to_ordinal(self): # @TODO: implement to_ordinal with self.assertRaises(NotImplementedError): - num2words(1, lang='cz', to='ordinal') + num2words(1, lang='cs', to='ordinal') def test_currency(self): self.assertEqual( - num2words(10.0, lang='cz', to='currency', currency='EUR'), + num2words(10.0, lang='cs', to='currency', currency='EUR'), "deset euro, nula centů") self.assertEqual( - num2words(1.0, lang='cz', to='currency', currency='CZK'), + num2words(1.0, lang='cs', to='currency', currency='CZK'), "jedna koruna, nula haléřů") self.assertEqual( - num2words(1234.56, lang='cz', to='currency', currency='EUR'), + num2words(1234.56, lang='cs', to='currency', currency='EUR'), "tisíc dvěstě třicet čtyři euro, padesát šest centů") self.assertEqual( - num2words(1234.56, lang='cz', to='currency', currency='CZK'), + num2words(1234.56, lang='cs', to='currency', currency='CZK'), "tisíc dvěstě třicet čtyři koruny, padesát šest haléřů") self.assertEqual( - num2words(101.11, lang='cz', to='currency', currency='EUR', + num2words(101.11, lang='cs', to='currency', currency='EUR', separator=' a'), "sto jedna euro a jedenáct centů") self.assertEqual( - num2words(101.21, lang='cz', to='currency', currency='CZK', + num2words(101.21, lang='cs', to='currency', currency='CZK', separator=' a'), "sto jedna korun a dvacet jedna haléřů" ) self.assertEqual( - num2words(-12519.85, lang='cz', to='currency', cents=False), + num2words(-12519.85, lang='cs', to='currency', cents=False), "mínus dvanáct tisíc pětset devatenáct euro, 85 centů" ) self.assertEqual( - num2words(123.50, lang='cz', to='currency', currency='CZK', + num2words(123.50, lang='cs', to='currency', currency='CZK', separator=' a'), "sto dvacet tři koruny a padesát haléřů" ) self.assertEqual( - num2words(19.50, lang='cz', to='currency', cents=False), + num2words(19.50, lang='cs', to='currency', cents=False), "devatenáct euro, 50 centů" ) From 282f72dd2ff226bc14ca6c4234b661eaac7ed8aa Mon Sep 17 00:00:00 2001 From: Rochdi Bazine Date: Mon, 16 Dec 2024 17:19:57 +0100 Subject: [PATCH 336/340] Added support for Tunisian Dinar (#593) * Added support for Tunisian Dinar * Added tests for TND currency * Set parPrecision for other AR currencies --------- Co-authored-by: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> --- num2words/lang_AR.py | 11 ++++++++++- tests/test_ar.py | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 7195dd47..7813d3aa 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -31,6 +31,8 @@ ("قرش", "قرشان", "قروش", "قرش")] CURRENCY_KWD = [("دينار", "ديناران", "دينارات", "ديناراً"), ("فلس", "فلسان", "فلس", "فلس")] +CURRENCY_TND = [("دينار", "ديناران", "دينارات", "ديناراً"), + ("مليماً", "ميلمان", "مليمات", "مليم")] ARABIC_ONES = [ "", "واحد", "اثنان", "ثلاثة", "أربعة", "خمسة", "ستة", "سبعة", "ثمانية", @@ -352,15 +354,22 @@ def validate_number(self, number): return number def set_currency_prefer(self, currency): - if currency == 'EGP': + if currency == 'TND': + self.currency_unit = CURRENCY_TND[0] + self.currency_subunit = CURRENCY_TND[1] + self.partPrecision = 3 + elif currency == 'EGP': self.currency_unit = CURRENCY_EGP[0] self.currency_subunit = CURRENCY_EGP[1] + self.partPrecision = 2 elif currency == 'KWD': self.currency_unit = CURRENCY_KWD[0] self.currency_subunit = CURRENCY_KWD[1] + self.partPrecision = 2 else: self.currency_unit = CURRENCY_SR[0] self.currency_subunit = CURRENCY_SR[1] + self.partPrecision = 2 def to_currency(self, value, currency='SR', prefix='', suffix=''): self.set_currency_prefer(currency) diff --git a/tests/test_ar.py b/tests/test_ar.py index 91e648a6..5781db52 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -66,6 +66,12 @@ def test_currency_parm(self): self.assertEqual( num2words(1000000.99, to='currency', lang='ar', currency="KWD"), 'مليون دينار و تسع و تسعون فلس') + self.assertEqual( + num2words(1000.42, to='currency', lang='ar', currency="TND"), + 'ألف دينار و أربعمائة و عشرون مليم') + self.assertEqual( + num2words(123.21, to='currency', lang='ar', currency="TND"), + 'مائة و ثلاثة و عشرون ديناراً و مئتان و عشر مليمات') def test_ordinal(self): From 6abe2c64714a38e41de23fe20fa319d0ad2fd845 Mon Sep 17 00:00:00 2001 From: Frederik Haa Date: Mon, 16 Dec 2024 17:34:18 +0100 Subject: [PATCH 337/340] Change danish language code to DA (#596) Co-authored-by: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> --- num2words/__init__.py | 4 ++-- num2words/{lang_DK.py => lang_DA.py} | 4 ++-- tests/{test_dk.py => test_da.py} | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) rename num2words/{lang_DK.py => lang_DA.py} (98%) rename tests/{test_dk.py => test_da.py} (68%) diff --git a/num2words/__init__.py b/num2words/__init__.py index 0c216ad2..882aa229 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_BN, lang_CA, lang_CE, - lang_CS, lang_CY, lang_DE, lang_DK, lang_EN, lang_EN_IN, + lang_CS, lang_CY, lang_DA, lang_DE, lang_EN, lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, lang_ES_CR, lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, @@ -69,7 +69,7 @@ 'sr': lang_SR.Num2Word_SR(), 'sv': lang_SV.Num2Word_SV(), 'no': lang_NO.Num2Word_NO(), - 'dk': lang_DK.Num2Word_DK(), + 'da': lang_DA.Num2Word_DA(), 'pt': lang_PT.Num2Word_PT(), 'pt_BR': lang_PT_BR.Num2Word_PT_BR(), 'he': lang_HE.Num2Word_HE(), diff --git a/num2words/lang_DK.py b/num2words/lang_DA.py similarity index 98% rename from num2words/lang_DK.py rename to num2words/lang_DA.py index 50ab110c..c6607383 100644 --- a/num2words/lang_DK.py +++ b/num2words/lang_DA.py @@ -20,12 +20,12 @@ from . import lang_EU -class Num2Word_DK(lang_EU.Num2Word_EU): +class Num2Word_DA(lang_EU.Num2Word_EU): GIGA_SUFFIX = "illiarder" MEGA_SUFFIX = "illioner" def setup(self): - super(Num2Word_DK, self).setup() + super(Num2Word_DA, self).setup() self.negword = "minus " self.pointword = "komma" diff --git a/tests/test_dk.py b/tests/test_da.py similarity index 68% rename from tests/test_dk.py rename to tests/test_da.py index 4c2e6ce3..3e1b4eba 100644 --- a/tests/test_dk.py +++ b/tests/test_da.py @@ -20,25 +20,25 @@ from unittest import TestCase from num2words import num2words -from num2words.lang_DK import Num2Word_DK +from num2words.lang_DA import Num2Word_DA class Num2WordsDKTest(TestCase): def test_ordinal(self): - self.assertEqual(num2words(1, to="ordinal", lang="dk"), "første") - self.assertEqual(num2words(5, to="ordinal", lang="dk"), "femte") + self.assertEqual(num2words(1, to="ordinal", lang="da"), "første") + self.assertEqual(num2words(5, to="ordinal", lang="da"), "femte") def test_cardinal(self): - self.assertEqual(num2words(0, to="cardinal", lang="dk"), "nul") - self.assertEqual(num2words(1, to="cardinal", lang="dk"), "et") - self.assertEqual(num2words(2, to="cardinal", lang="dk"), "to") - self.assertEqual(num2words(5, to="cardinal", lang="dk"), "fem") - self.assertEqual(num2words(8, to="cardinal", lang="dk"), "otte") - self.assertEqual(num2words(18, to="cardinal", lang="dk"), "atten") - self.assertEqual(num2words(45, to="cardinal", lang="dk"), "femogfyrre") + self.assertEqual(num2words(0, to="cardinal", lang="da"), "nul") + self.assertEqual(num2words(1, to="cardinal", lang="da"), "et") + self.assertEqual(num2words(2, to="cardinal", lang="da"), "to") + self.assertEqual(num2words(5, to="cardinal", lang="da"), "fem") + self.assertEqual(num2words(8, to="cardinal", lang="da"), "otte") + self.assertEqual(num2words(18, to="cardinal", lang="da"), "atten") + self.assertEqual(num2words(45, to="cardinal", lang="da"), "femogfyrre") def test_to_ordinal_num(self): - num2words_dk = Num2Word_DK() + num2words_dk = Num2Word_DA() self.assertEqual(num2words_dk.to_ordinal_num(1), "1te") self.assertEqual(num2words_dk.to_ordinal_num(2), "2en") self.assertEqual(num2words_dk.to_ordinal_num(5), "5te") From 2b4d0bbef8354aa6fbdee8ff4b7da95a35922a9a Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:00:01 -0500 Subject: [PATCH 338/340] New release (#606) Co-authored-by: Marlon Rodriguez Garcia --- CHANGES.rst | 17 +++++++++++++++++ README.rst | 16 +++++++++------- bin/num2words | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ea33f3e2..32a6e616 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,23 @@ Changelog ========= +Version 0.5.14 -- 2024/12/16 +---------------------------- + +* Fixed a typo in PL (#466) +* Run tests against Python 3.12 (#544) +* ADD num2words: es_CR language (#565) +* New languages: Welsh (Celtic) and Chechen (Nakho-Dagestanian) (#543) +* Add catalan language support (#581) +* Adding Tetum Language (#576) +* FIX ISO code for Belarusian language is be, not by. (#574) +* Add test to improve coverage (#595) +* Added Bangla language support to num2word for Bangladesh. (#589) +* Czech language ISO 639-1 code fix (#587) +* Added support for Tunisian Dinar (#593) +* Change danish language code to DA (#596) + + Version 0.5.13 -- 2023/10/18 --------------------------- diff --git a/README.rst b/README.rst index 16d33f59..7e0bc1f2 100644 --- a/README.rst +++ b/README.rst @@ -81,25 +81,26 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``az`` (Azerbaijani) * ``be`` (Belarusian) * ``bn`` (Bangladeshi) +* ``ca`` (Catalan) * ``ce`` (Chechen) * ``cs`` (Czech) * ``cy`` (Welsh) +* ``da`` (Danish) * ``de`` (German) -* ``dk`` (Danish) * ``en_GB`` (English - Great Britain) * ``en_IN`` (English - India) * ``en_NG`` (English - Nigeria) * ``es`` (Spanish) * ``es_CO`` (Spanish - Colombia) * ``es_CR`` (Spanish - Costa Rica) -* ``es_VE`` (Spanish - Venezuela) * ``es_GT`` (Spanish - Guatemala) +* ``es_VE`` (Spanish - Venezuela) * ``eu`` (EURO) * ``fa`` (Farsi) * ``fi`` (Finnish) * ``fr`` (French) -* ``fr_CH`` (French - Switzerland) * ``fr_BE`` (French - Belgium) +* ``fr_CH`` (French - Switzerland) * ``fr_DZ`` (French - Algeria) * ``he`` (Hebrew) * ``hu`` (Hungarian) @@ -112,23 +113,24 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``kz`` (Kazakh) * ``lt`` (Lithuanian) * ``lv`` (Latvian) +* ``nl`` (Dutch) * ``no`` (Norwegian) * ``pl`` (Polish) * ``pt`` (Portuguese) * ``pt_BR`` (Portuguese - Brazilian) +* ``ro`` (Romanian) +* ``ru`` (Russian) * ``sl`` (Slovene) +* ``sk`` (Slovak) * ``sr`` (Serbian) * ``sv`` (Swedish) -* ``ro`` (Romanian) -* ``ru`` (Russian) * ``te`` (Telugu) * ``tet`` (Tetum) * ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) -* ``vi`` (Vietnamese) -* ``nl`` (Dutch) * ``uk`` (Ukrainian) +* ``vi`` (Vietnamese) You can supply values like ``fr_FR``; if the country doesn't exist but the language does, the code will fall back to the base language (i.e. ``fr``). If diff --git a/bin/num2words b/bin/num2words index 359d1bdb..c6dbd52f 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.13" +__version__ = "0.5.14" __license__ = "LGPL" From 1e6e57f1130b3cb203d43bb442c2462d44d89c9f Mon Sep 17 00:00:00 2001 From: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:03:21 -0500 Subject: [PATCH 339/340] Updated python versions, removed 3.7 and added 3.13 (#609) Co-authored-by: Marlon Rodriguez Garcia --- .github/workflows/ci.yml | 2 +- setup.py | 2 +- tox.ini | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68330d4c..f843e4e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 4ca9fda6..df9c30ba 100644 --- a/setup.py +++ b/setup.py @@ -27,12 +27,12 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU Library or Lesser General Public License ' '(LGPL)', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', diff --git a/tox.ini b/tox.ini index 63e88f3a..b896391e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,14 @@ [tox] -envlist = py37,py38,py39,py310,py311,py312,flake8,isort +envlist = py38,py39,py310,py311,py312,py313,flake8,isort [gh-actions] python = - 3.7: py37 3.8: py38 3.9: py39 3.10: isort, flake8, py310 3.11: py311 3.12: py312 + 3.13: py313 [testenv] From beca211923e2843e64f7237e5da2d9e930e76af6 Mon Sep 17 00:00:00 2001 From: Bryan Anderson Date: Mon, 6 Jan 2025 08:23:28 -0800 Subject: [PATCH 340/340] Add yen (JPY) and won (KRW) for European languages (#604) Co-authored-by: Marlon Rodriguez Garcia <47992153+mrodriguezg1991@users.noreply.github.com> --- num2words/lang_EU.py | 8 ++++++-- tests/test_en.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 0ff74ab2..8579fb60 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -47,7 +47,9 @@ class Num2Word_EU(Num2Word_Base): 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), 'ISK': (('króna', 'krónur'), ('aur', 'aurar')), 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')), - 'SAR': (('saudi riyal', 'saudi riyals'), ('halalah', 'halalas')) + 'SAR': (('saudi riyal', 'saudi riyals'), ('halalah', 'halalas')), + 'JPY': (('yen', 'yen'), ('sen', 'sen')), + 'KRW': (('won', 'won'), ('jeon', 'jeon')), } @@ -65,7 +67,9 @@ class Num2Word_EU(Num2Word_Base): 'HUF': 'Hungarian', 'ISK': 'íslenskar', 'UZS': 'Uzbekistan', - 'SAR': 'Saudi' + 'SAR': 'Saudi', + 'JPY': 'Japanese', + 'KRW': 'Korean', } GIGA_SUFFIX = "illiard" diff --git a/tests/test_en.py b/tests/test_en.py index e763841c..4ab267c6 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -137,6 +137,18 @@ def test_to_currency(self): "two thousand sums and zero tiyins" ) + self.assertEqual( + num2words('2000.00', lang='en', to='currency', separator=' and', + cents=True, currency='JPY'), + "two thousand yen and zero sen" + ) + + self.assertEqual( + num2words('2000.00', lang='en', to='currency', separator=' and', + cents=True, currency='KRW'), + "two thousand won and zero jeon" + ) + def test_to_year(self): # issue 141 # "e2 e2"