From ce21cb9f1806268834a8f9b5ec4e80623d580438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Honor=C3=A9=20=28Acsone=29?= <30529208+acsonefho@users.noreply.github.com> Date: Tue, 16 Jan 2018 20:38:43 +0100 Subject: [PATCH] [ADD] Add lang fr_BE + tests (#151) --- .gitignore | 1 + README.rst | 1 + num2words/__init__.py | 2 + num2words/lang_FR_BE.py | 49 +++++++++++++++ tests/test_fr_be.py | 129 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 num2words/lang_FR_BE.py create mode 100644 tests/test_fr_be.py diff --git a/.gitignore b/.gitignore index d578da0..5e0679e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.pyc build dist +.idea/ *.egg-info /.tox diff --git a/README.rst b/README.rst index c9fbd67..2c093b4 100644 --- a/README.rst +++ b/README.rst @@ -72,6 +72,7 @@ Besides the numerical argument, there's two optional arguments. * ``eu`` (EURO) * ``fr`` (French) * ``fr_CH`` (French - Switzerland) +* ``fr_BE`` (French - Belgium) * ``fr_DZ`` (French - Algeria) * ``he`` (Hebrew) * ``id`` (Indonesian) diff --git a/num2words/__init__.py b/num2words/__init__.py index 389ce25..9f7c337 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -21,6 +21,7 @@ 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 @@ -49,6 +50,7 @@ CONVERTER_CLASSES = { 'en_IN': lang_EN_IN.Num2Word_EN_IN(), 'fr': lang_FR.Num2Word_FR(), 'fr_CH': lang_FR_CH.Num2Word_FR_CH(), + 'fr_BE': lang_FR_BE.Num2Word_FR_BE(), 'fr_DZ': lang_FR_DZ.Num2Word_FR_DZ(), 'de': lang_DE.Num2Word_DE(), 'es': lang_ES.Num2Word_ES(), diff --git a/num2words/lang_FR_BE.py b/num2words/lang_FR_BE.py new file mode 100644 index 0000000..5c73a0e --- /dev/null +++ b/num2words/lang_FR_BE.py @@ -0,0 +1,49 @@ +# -*- 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 print_function, unicode_literals + +from .lang_FR import Num2Word_FR + + +class Num2Word_FR_BE(Num2Word_FR): + def setup(self): + Num2Word_FR.setup(self) + + self.mid_numwords = [(1000, "mille"), (100, "cent"), (90, "nonante"), + (80, "quatre-vingt"), (70, "septante"), + (60, "soixante"), (50, "cinquante"), + (40, "quarante"), (30, "trente")] + + def merge(self, curr, next): + ctext, cnum, ntext, nnum = curr + next + + if cnum == 1: + if nnum < 1000000: + return next + + if cnum < 1000 and nnum != 1000 and\ + ntext[-1] != "s" and not nnum % 100: + ntext += "s" + + if nnum < cnum < 100: + if nnum % 10 == 1: + return ("%s et %s" % (ctext, ntext), cnum + nnum) + return ("%s-%s" % (ctext, ntext), cnum + nnum) + if nnum > cnum: + return ("%s %s" % (ctext, ntext), cnum * nnum) + return ("%s %s" % (ctext, ntext), cnum + nnum) diff --git a/tests/test_fr_be.py b/tests/test_fr_be.py new file mode 100644 index 0000000..560d433 --- /dev/null +++ b/tests/test_fr_be.py @@ -0,0 +1,129 @@ +# -*- encoding: utf-8 -*- +# Copyright (c) 2015, 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 = ( + (70, 'septante'), + (79, 'septante-neuf'), + (89, 'quatre-vingt-neuf'), + (95, 'nonante-cinq'), + (729, 'sept cents vingt-neuf'), + (894, 'huit cents nonante-quatre'), + (999, 'neuf cents nonante-neuf'), + (7232, 'sept mille deux cents trente-deux'), + (8569, 'huit mille cinq cents soixante-neuf'), + (9539, 'neuf mille cinq cents trente-neuf'), + (1000000, 'un millions'), + (1000001, 'un millions un'), + (4000000, 'quatre millions'), + (10000000000000, 'dix billions'), + (100000000000000, 'cent billions'), + (1000000000000000000, 'un trillions'), + (1000000000000000000000, 'un trilliards'), + (10000000000000000000000000, 'dix quadrillions') +) + +TEST_CASES_ORDINAL = ( + (1, 'premier'), + (8, 'huitième'), + (12, 'douzième'), + (14, 'quatorzième'), + (28, 'vingt-huitième'), + (100, 'centième'), + (1000, 'millième'), + (1000000, 'un millionsième'), + (1000000000000000, 'un billiardsième'), + (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'), + (81.25, 'quatre-vingt et un euros et vingt-cinq centimes'), + (100, 'cent euros'), +) + +TEST_CASES_TO_CURRENCY_OLD = ( + (1, 'un franc'), + (2, 'deux francs'), + (8, 'huit francs'), + (12, 'douze francs'), + (21, 'vingt et un francs'), + (81.25, 'quatre-vingt et un francs et vingt-cinq centimes'), + (100, 'cent francs'), +) + +# Lang to execute current test +LANG = 'fr_BE' + + +class Num2WordsENTest(TestCase): + def test_ordinal_special_joins(self): + self.assertEqual( + num2words(5, ordinal=True, lang=LANG), "cinquième" + ) + self.assertEqual( + num2words(6, ordinal=True, lang=LANG), "sixième" + ) + self.assertEqual( + num2words(35, ordinal=True, lang=LANG), "trente-cinquième" + ) + self.assertEqual(num2words(9, ordinal=True, lang=LANG), "neuvième") + self.assertEqual( + num2words(49, ordinal=True, lang=LANG), "quarante-neuvième" + ) + self.assertEqual(num2words(71, lang=LANG), "septante et un") + self.assertEqual(num2words(81, lang=LANG), "quatre-vingt et un") + self.assertEqual(num2words(80, lang=LANG), "quatre-vingt") + self.assertEqual( + num2words(880, lang=LANG), "huit cents quatre-vingt") + self.assertEqual( + num2words(91, ordinal=True, lang=LANG), "nonante et unième" + ) + self.assertEqual(num2words(53, lang=LANG), "cinquante-trois") + + def test_number(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang=LANG), test[1]) + + def test_ordinal(self): + for test in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang=LANG, ordinal=True), + test[1] + ) + + def test_currency(self): + for test in TEST_CASES_TO_CURRENCY: + self.assertEqual( + num2words(test[0], lang=LANG, to='currency'), + test[1] + ) + + def test_currency_old(self): + for test in TEST_CASES_TO_CURRENCY_OLD: + self.assertEqual( + num2words(test[0], lang=LANG, to='currency', old=True), + test[1] + )