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/README.rst b/README.rst index 743b5439..c24bb099 100644 --- a/README.rst +++ b/README.rst @@ -97,6 +97,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/__init__.py b/num2words/__init__.py index 1c438486..0e6b89cf 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -20,11 +20,11 @@ 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, - 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_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(), @@ -71,7 +71,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_EU.py b/num2words/lang_EU.py index 3e91ed19..f2336701 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -45,7 +45,9 @@ class Num2Word_EU(Num2Word_Base): 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), + 'ISK': (('króna', 'krónur'), ('aur', 'aurar')), 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')) + } CURRENCY_ADJECTIVES = { @@ -60,6 +62,7 @@ class Num2Word_EU(Num2Word_Base): 'RON': 'Romanian', 'INR': 'Indian', 'HUF': 'Hungarian', + 'ISK': 'íslenskar', 'UZS': 'Uzbekistan' } diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py new file mode 100644 index 00000000..e29eb7a7 --- /dev/null +++ b/num2words/lang_IS.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from __future__ import division, print_function, unicode_literals + +from . import lang_EU + +# Genders +KK = 0 # Karlkyn (male) +KVK = 1 # Kvenkyn (female) +HK = 2 # Hvorugkyn (neuter) + +GENDERS = { + "einn": ("einn", "ein", "eitt"), + "tveir": ("tveir", "tvær", "tvö"), + "þrír": ("þrír", "þrjár", "þrjú"), + "fjórir": ("fjórir", "fjórar", "fjögur"), +} + +PLURALS = { + "hundrað": ("hundrað", "hundruð"), +} + + +class Num2Word_IS(lang_EU.Num2Word_EU): + + GIGA_SUFFIX = "illjarður" + MEGA_SUFFIX = "illjón" + + def setup(self): + lows = ["okt", "sept", "sext", "kvint", "kvaðr", "tr", "b", "m"] + self.high_numwords = self.gen_high_numwords([], [], lows) + + self.negword = "mínus " + self.pointword = "komma" + + # All words should be excluded, title case is not used in Icelandic + self.exclude_title = ["og", "komma", "mínus"] + + self.mid_numwords = [(1000, "þúsund"), (100, "hundrað"), + (90, "níutíu"), (80, "áttatíu"), (70, "sjötíu"), + (60, "sextíu"), (50, "fimmtíu"), (40, "fjörutíu"), + (30, "þrjátíu")] + self.low_numwords = ["tuttugu", "nítján", "átján", "sautján", + "sextán", "fimmtán", "fjórtán", "þrettán", + "tólf", "ellefu", "tíu", "níu", "átta", + "sjö", "sex", "fimm", "fjórir", "þrír", + "tveir", "einn", "núll"] + self.ords = {"einn": "fyrsti", + "tveir": "annar", + "þrír": "þriðji", + "fjórir": "fjórði", + "fimm": "fimmti", + "sex": "sjötti", + "sjö": "sjöundi", + "átta": "áttundi", + "níu": "níundi", + "tíu": "tíundi", + "ellefu": "ellefti", + "tólf": "tólfti"} + + def pluralize(self, n, noun): + form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 + if form == 0: + return noun + elif self.GIGA_SUFFIX in noun: + return noun.replace(self.GIGA_SUFFIX, "illjarðar") + elif self.MEGA_SUFFIX in noun: + return noun.replace(self.MEGA_SUFFIX, "illjónir") + elif noun not in PLURALS: + return noun + return PLURALS[noun][form] + + def genderize(self, adj, noun): + last = adj.split()[-1] + if last not in GENDERS: + return adj + gender = KK + if "hund" in noun or "þús" in noun: + gender = HK + elif "illjarð" in noun: + gender = KK + elif "illjón" in noun: + gender = KVK + return adj.replace(last, GENDERS[last][gender]) + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif lnum < rnum: + rtext = self.pluralize(lnum, rtext) + ltext = self.genderize(ltext, rtext) + return ("%s %s" % (ltext, rtext), lnum * rnum) + elif lnum > rnum and rnum in self.cards: + rtext = self.pluralize(lnum, rtext) + ltext = self.genderize(ltext, rtext) + return ("%s og %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + raise NotImplementedError + + def to_ordinal_num(self, value): + raise NotImplementedError + + def to_year(self, val, suffix=None, longval=True): + raise NotImplementedError + + def to_currency(self, val, longval=True): + raise NotImplementedError diff --git a/tests/test_is.py b/tests/test_is.py new file mode 100644 index 00000000..2a836d51 --- /dev/null +++ b/tests/test_is.py @@ -0,0 +1,79 @@ +# coding: utf-8 +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +from __future__ import unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsISTest(TestCase): + + def test_cardinal(self): + self.assertEqual(num2words(0, to="cardinal", lang="is"), + "núll") + self.assertEqual(num2words(1, to="cardinal", lang="is"), + "einn") + self.assertEqual(num2words(45, to="cardinal", lang="is"), + "fjörutíu og fimm") + self.assertEqual(num2words(145, to="cardinal", lang="is"), + "eitt hundrað fjörutíu og fimm") + self.assertEqual(num2words(-1245, to="cardinal", lang="is"), + "mínus eitt þúsund tvö hundruð fjörutíu og fimm") + self.assertEqual(num2words(2234045, to="cardinal", lang="is"), + "tvær milljónir tvö hundruð þrjátíu og fjögur þúsund " + "fjörutíu og fimm") + self.assertEqual(num2words(4002234045, to="cardinal", lang="is"), + "fjórir milljarðar tvær milljónir tvö hundruð " + "þrjátíu og fjögur þúsund fjörutíu og fimm") + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, to="cardinal", lang="is"), + "tólf komma fimm") + self.assertEqual(num2words(12.51, to="cardinal", lang="is"), + "tólf komma fimm einn") + self.assertEqual(num2words(-12.53, to="cardinal", lang="is"), + "mínus tólf komma fimm þrír") + self.assertEqual(num2words(12.59, to="cardinal", lang="is"), + "tólf komma fimm níu") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", lang="is") + + def test_not_implemented(self): + # Ordinals + with self.assertRaises(NotImplementedError): + num2words(1, to="ordinal", lang="is") + + # Ordinal num + with self.assertRaises(NotImplementedError): + num2words(1, to="ordinal_num", lang="is") + + # Year + with self.assertRaises(NotImplementedError): + num2words(1, to="year", lang="is") + + # Currency + with self.assertRaises(NotImplementedError): + num2words(1, to="currency", lang="is")