diff --git a/num2words/currency.py b/num2words/currency.py index c28c82a..ecf10b9 100644 --- a/num2words/currency.py +++ b/num2words/currency.py @@ -35,3 +35,7 @@ def parse_currency_parts(value): cents = int(fraction) return integer, cents, negative + + +def prefix_currency(prefix, base): + return tuple("%s %s" % (prefix, i) for i in base) diff --git a/num2words/lang_EN.py b/num2words/lang_EN.py index 685a9fb..fd6fc58 100644 --- a/num2words/lang_EN.py +++ b/num2words/lang_EN.py @@ -86,7 +86,10 @@ class Num2Word_EN(lang_EU.Num2Word_EU): return self.to_splitnum(val, hightxt="hundred", jointxt="and", longval=longval) - def to_currency(self, val, longval=True): + def to_currency(self, val, longval=True, **kwargs): + if 'currency' in kwargs: + return self._to_currency(val, **kwargs) + return self.to_splitnum(val, hightxt="dollar/s", lowtxt="cent/s", jointxt="and", longval=longval, cents=True) diff --git a/num2words/lang_EN_EUR.py b/num2words/lang_EN_EUR.py index a2a4943..04db601 100644 --- a/num2words/lang_EN_EUR.py +++ b/num2words/lang_EN_EUR.py @@ -20,7 +20,11 @@ from .lang_EN import Num2Word_EN class Num2Word_EN_EUR(Num2Word_EN): - def to_currency(self, val, longval=True, cents=True, jointxt="and"): + def to_currency(self, val, longval=True, cents=True, jointxt="and", + **kwargs): + if 'currency' in kwargs: + return self._to_currency(val, **kwargs) + return self.to_splitnum(val, hightxt="euro/s", lowtxt="cents", jointxt=jointxt, longval=longval, cents=cents) diff --git a/num2words/lang_EN_GB.py b/num2words/lang_EN_GB.py index 81f0605..59a7cfc 100644 --- a/num2words/lang_EN_GB.py +++ b/num2words/lang_EN_GB.py @@ -20,7 +20,10 @@ from .lang_EN import Num2Word_EN class Num2Word_EN_GB(Num2Word_EN): - def to_currency(self, val, longval=True): + def to_currency(self, val, longval=True, **kwargs): + if 'currency' in kwargs: + return self._to_currency(val, **kwargs) + return self.to_splitnum(val, hightxt="pound/s", lowtxt="pence", jointxt="and", longval=longval) diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index dc554c3..85a9a1a 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- # Copyright (c) 2003, Taro Ogawa. All Rights Reserved. # Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. @@ -17,6 +18,45 @@ from __future__ import unicode_literals from .base import Num2Word_Base +from .currency import parse_currency_parts, prefix_currency + +GENERIC_DOLLARS = ('dollar', 'dollars') +GENERIC_CENTS = ('cent', 'cents') + +""" +Source: http://publications.europa.eu/code/en/en-5000500.htm +""" +CURRENCIES = { + 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), + # repalced by EUR + 'EEK': (('kroon', 'kroons'), ('sent', 'senti')), + 'EUR': (('euro', 'euro'), GENERIC_CENTS), + 'GBP': (('pound sterling', 'pounds sterling'), ('penny', 'pence')), + # replaced by EUR + 'LTL': ('litas', 'litas', GENERIC_CENTS), + # replaced by EUR + 'LVL': (('lat', 'lats'), ('santim', 'santims')), + 'USD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'RUB': (('rouble', 'roubles'), ('kopek', 'kopeks')), + 'SEK': (('krona', 'kronor'), ('öre', 'öre')), + 'NOK': (('krone', 'kroner'), ('øre', 'øre')), + 'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')), +} + +PREFIXES = { + 'AUD': 'Australian', + 'CAD': 'Canadian', + 'EEK': 'Estonian', + 'USD': 'US', + 'RUB': 'Russian', + 'NOK': 'Norwegian', +} + + +def pluralize(n, forms): + form = 0 if n == 1 else 1 + return forms[form] class Num2Word_EU(Num2Word_Base): @@ -36,6 +76,29 @@ class Num2Word_EU(Num2Word_Base): self.high_numwords = ["cent"] + self.gen_high_numwords(units, tens, lows) - def to_currency(self, val, longval=True, jointxt=""): + def to_currency(self, val, longval=True, jointxt="", **kwargs): + if 'currency' in kwargs: + return self._to_currency(val, **kwargs) + return self.to_splitnum(val, hightxt="Euro/s", lowtxt="Euro cent/s", jointxt=jointxt, longval=longval) + + def _to_currency(self, val, currency='EUR', cents=True, seperator=',', + prefix=False): + left, right, is_negative = parse_currency_parts(val) + cr1, cr2 = CURRENCIES[currency] + + if prefix and currency in PREFIXES: + cr1 = prefix_currency(PREFIXES[currency], cr1) + + minus_str = "minus " if is_negative else "" + cents_str = self.to_cardinal(right) if cents else "%02d" % right + + return u'%s%s %s%s %s %s' % ( + minus_str, + self.to_cardinal(left), + pluralize(left, cr1), + seperator, + cents_str, + pluralize(right, cr2) + ) diff --git a/num2words/lang_LV.py b/num2words/lang_LV.py index 867ae66..c7073ec 100644 --- a/num2words/lang_LV.py +++ b/num2words/lang_LV.py @@ -99,7 +99,7 @@ mīnus divpadsmit tūkstoši pieci simti deviņpadsmit eiro, 85 centi """ from __future__ import unicode_literals -from .currency import parse_currency_parts +from .currency import parse_currency_parts, prefix_currency ZERO = ('nulle',) @@ -157,17 +157,10 @@ THOUSANDS = { GENERIC_DOLLARS = ('dolārs', 'dolāri', 'dolāru') GENERIC_CENTS = ('cents', 'centi', 'centu') -GENERIC_POUND = ('mārciņa', 'mārciņas', 'mārciņu') -GENERIC_PENCE = ('penss', 'pensi', 'pensu') - GENERIC_KRONA = ('krona', 'kronas', 'kronu') GENERIC_ERA = ('ēre', 'ēras', 'ēru') -def prefix_currency(prefix, base): - return tuple("%s %s" % (prefix, i) for i in base) - - """ Sadly we have a legal form (used in legal and finance documents): http://www.eiro.lv/files/upload/files/Eiro_rakstiba-1.pdf @@ -177,25 +170,36 @@ http://eur-lex.europa.eu/legal-content/LV/TXT/HTML/?uri=CELEX:31998R0974&from=LV Source: http://publications.europa.eu/code/lv/lv-5000500.htm """ CURRENCIES = { - 'AUD': (prefix_currency('Austrālijas', GENERIC_DOLLARS), GENERIC_CENTS), - 'CAD': (prefix_currency('Kanādas', GENERIC_DOLLARS), GENERIC_CENTS), + 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), # repalced by EUR - 'EEK': (prefix_currency('Igaunijas', GENERIC_KRONA), GENERIC_CENTS), + 'EEK': (GENERIC_KRONA, GENERIC_CENTS), 'EUR': (('eiro', 'eiro', 'eiro'), GENERIC_CENTS), 'EUR_LEGAL': (('euro', 'euro', 'euro'), GENERIC_CENTS), - 'GBP': (prefix_currency('sterliņu', GENERIC_POUND), GENERIC_PENCE), + 'GBP': ( + ('sterliņu mārciņa', 'sterliņu mārciņas', 'sterliņu mārciņu'), + ('penss', 'pensi', 'pensu')), # replaced by EUR 'LTL': ('lits', 'liti', 'litu', GENERIC_CENTS), # replaced by EUR 'LVL': (('lats', 'lati', 'latu'), ('santīms', 'santīmi', 'santīmu')), - 'USD': (prefix_currency('ASV', GENERIC_DOLLARS), GENERIC_CENTS), - 'RUB': (prefix_currency('Krievijas', ('rublis', 'rubļi', 'rubļu')), - ('kapeika', 'kapeikas', 'kapeiku')), - 'SEK': (prefix_currency('Zviedrijas', GENERIC_KRONA), GENERIC_ERA), - 'NOK': (prefix_currency('Norvēģijas', GENERIC_KRONA), GENERIC_ERA), + 'USD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'RUB': (('rublis', 'rubļi', 'rubļu'), ('kapeika', 'kapeikas', 'kapeiku')), + 'SEK': (GENERIC_KRONA, GENERIC_ERA), + 'NOK': (GENERIC_KRONA, GENERIC_ERA), 'PLN': (('zlots', 'zloti', 'zlotu'), ('grasis', 'graši', 'grašu')), } +PREFIXES = { + 'AUD': 'Austrālijas', + 'CAD': 'Kanādas', + 'EEK': 'Igaunijas', + 'USD': 'ASV', + 'RUB': 'Kreivijas', + 'SEK': 'Zviedrijas', + 'NOK': 'Norvēģijas', +} + def splitby3(n): length = len(n) @@ -261,10 +265,13 @@ def n2w(n): return int2word(int(n)) -def to_currency(n, currency='EUR', cents=True, seperator=','): +def to_currency(n, currency='EUR', cents=True, seperator=',', prefix=False): left, right, is_negative = parse_currency_parts(n) cr1, cr2 = CURRENCIES[currency] + if prefix and currency in PREFIXES: + cr1 = prefix_currency(PREFIXES[currency], cr1) + minus_str = "mīnus " if is_negative else "" cents_str = int2word(right) if cents else "%02d" % right @@ -285,8 +292,9 @@ class Num2Word_LV(object): def to_ordinal(self, number): raise NotImplementedError() - def to_currency(self, n, currency='EUR', cents=True, seperator=','): - return to_currency(n, currency, cents, seperator) + def to_currency(self, n, currency='EUR', cents=True, seperator=',', + prefix=False): + return to_currency(n, currency, cents, seperator, prefix) if __name__ == '__main__': diff --git a/tests/test_en.py b/tests/test_en.py index ac06d98..fe4c77c 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -29,3 +29,33 @@ class Num2WordsENTest(TestCase): self.assertEqual(num2words(12.51), "twelve point five one") self.assertEqual(num2words(12.53), "twelve point five three") self.assertEqual(num2words(12.59), "twelve point five nine") + + def test_to_currency(self): + self.assertEqual( + num2words('38.4', lang='en', to='currency', seperator=' and', + cents=False, currency='USD'), + "thirty-eight dollars and 40 cents" + ) + self.assertEqual( + num2words('0', lang='en', to='currency', seperator=' and', + cents=False, currency='USD'), + "zero dollars and 00 cents" + ) + + self.assertEqual( + num2words('1.01', lang='en', to='currency', seperator=' and', + cents=True, currency='USD'), + "one dollar and one cent" + ) + + self.assertEqual( + num2words('4778.00', lang='en', to='currency', seperator=' and', + cents=True, currency='USD', prefix=True), + 'four thousand, seven hundred and seventy-eight US dollars' + ' and zero cents') + + self.assertEqual( + num2words('4778.00', lang='en', to='currency', seperator=' and', + cents=True, currency='USD'), + 'four thousand, seven hundred and seventy-eight dollars and' + ' zero cents') diff --git a/tests/test_lv.py b/tests/test_lv.py index 62f8d51..b7f20c2 100644 --- a/tests/test_lv.py +++ b/tests/test_lv.py @@ -41,7 +41,13 @@ class Num2WordsLVTest(TestCase): self.assertEqual( num2words('38.4', lang='lv', to='currency', seperator=' un', - cents=False, currency='USD'), + cents=False, currency='USD', prefix=False), + "trīsdesmit astoņi dolāri un 40 centi" + ) + + self.assertEqual( + num2words('38.4', lang='lv', to='currency', seperator=' un', + cents=False, currency='USD', prefix=True), "trīsdesmit astoņi ASV dolāri un 40 centi" )