Long form for currency name is optional. Currency name rendering in e… (#133)

* Long form for currency name is optional. Currency name rendering in english.

* Missing encoding header.
This commit is contained in:
Mārtiņš Šulcs
2017-11-06 00:59:25 +02:00
committed by Ernesto Rodriguez Ortiz
parent ee9f767b06
commit 5a131fedc6
8 changed files with 146 additions and 25 deletions

View File

@@ -35,3 +35,7 @@ def parse_currency_parts(value):
cents = int(fraction) cents = int(fraction)
return integer, cents, negative return integer, cents, negative
def prefix_currency(prefix, base):
return tuple("%s %s" % (prefix, i) for i in base)

View File

@@ -86,7 +86,10 @@ class Num2Word_EN(lang_EU.Num2Word_EU):
return self.to_splitnum(val, hightxt="hundred", jointxt="and", return self.to_splitnum(val, hightxt="hundred", jointxt="and",
longval=longval) 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", return self.to_splitnum(val, hightxt="dollar/s", lowtxt="cent/s",
jointxt="and", longval=longval, cents=True) jointxt="and", longval=longval, cents=True)

View File

@@ -20,7 +20,11 @@ from .lang_EN import Num2Word_EN
class Num2Word_EN_EUR(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", return self.to_splitnum(val, hightxt="euro/s", lowtxt="cents",
jointxt=jointxt, longval=longval, cents=cents) jointxt=jointxt, longval=longval, cents=cents)

View File

@@ -20,7 +20,10 @@ from .lang_EN import Num2Word_EN
class Num2Word_EN_GB(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", return self.to_splitnum(val, hightxt="pound/s", lowtxt="pence",
jointxt="and", longval=longval) jointxt="and", longval=longval)

View File

@@ -1,3 +1,4 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. # Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. # Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
@@ -17,6 +18,45 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from .base import Num2Word_Base 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): class Num2Word_EU(Num2Word_Base):
@@ -36,6 +76,29 @@ class Num2Word_EU(Num2Word_Base):
self.high_numwords = ["cent"] + self.gen_high_numwords(units, tens, self.high_numwords = ["cent"] + self.gen_high_numwords(units, tens,
lows) 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", return self.to_splitnum(val, hightxt="Euro/s", lowtxt="Euro cent/s",
jointxt=jointxt, longval=longval) 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)
)

View File

@@ -99,7 +99,7 @@ mīnus divpadsmit tūkstoši pieci simti deviņpadsmit eiro, 85 centi
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from .currency import parse_currency_parts from .currency import parse_currency_parts, prefix_currency
ZERO = ('nulle',) ZERO = ('nulle',)
@@ -157,17 +157,10 @@ THOUSANDS = {
GENERIC_DOLLARS = ('dolārs', 'dolāri', 'dolāru') GENERIC_DOLLARS = ('dolārs', 'dolāri', 'dolāru')
GENERIC_CENTS = ('cents', 'centi', 'centu') 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_KRONA = ('krona', 'kronas', 'kronu')
GENERIC_ERA = ('ēre', 'ēras', 'ēru') 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): Sadly we have a legal form (used in legal and finance documents):
http://www.eiro.lv/files/upload/files/Eiro_rakstiba-1.pdf 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 Source: http://publications.europa.eu/code/lv/lv-5000500.htm
""" """
CURRENCIES = { CURRENCIES = {
'AUD': (prefix_currency('Austrālijas', GENERIC_DOLLARS), GENERIC_CENTS), 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (prefix_currency('Kanādas', GENERIC_DOLLARS), GENERIC_CENTS), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
# repalced by EUR # repalced by EUR
'EEK': (prefix_currency('Igaunijas', GENERIC_KRONA), GENERIC_CENTS), 'EEK': (GENERIC_KRONA, GENERIC_CENTS),
'EUR': (('eiro', 'eiro', 'eiro'), GENERIC_CENTS), 'EUR': (('eiro', 'eiro', 'eiro'), GENERIC_CENTS),
'EUR_LEGAL': (('euro', 'euro', 'euro'), 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 # replaced by EUR
'LTL': ('lits', 'liti', 'litu', GENERIC_CENTS), 'LTL': ('lits', 'liti', 'litu', GENERIC_CENTS),
# replaced by EUR # replaced by EUR
'LVL': (('lats', 'lati', 'latu'), ('santīms', 'santīmi', 'santīmu')), 'LVL': (('lats', 'lati', 'latu'), ('santīms', 'santīmi', 'santīmu')),
'USD': (prefix_currency('ASV', GENERIC_DOLLARS), GENERIC_CENTS), 'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
'RUB': (prefix_currency('Krievijas', ('rublis', 'rubļi', 'rubļu')), 'RUB': (('rublis', 'rubļi', 'rubļu'), ('kapeika', 'kapeikas', 'kapeiku')),
('kapeika', 'kapeikas', 'kapeiku')), 'SEK': (GENERIC_KRONA, GENERIC_ERA),
'SEK': (prefix_currency('Zviedrijas', GENERIC_KRONA), GENERIC_ERA), 'NOK': (GENERIC_KRONA, GENERIC_ERA),
'NOK': (prefix_currency('Norvēģijas', GENERIC_KRONA), GENERIC_ERA),
'PLN': (('zlots', 'zloti', 'zlotu'), ('grasis', 'graši', 'grašu')), '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): def splitby3(n):
length = len(n) length = len(n)
@@ -261,10 +265,13 @@ def n2w(n):
return int2word(int(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) left, right, is_negative = parse_currency_parts(n)
cr1, cr2 = CURRENCIES[currency] cr1, cr2 = CURRENCIES[currency]
if prefix and currency in PREFIXES:
cr1 = prefix_currency(PREFIXES[currency], cr1)
minus_str = "mīnus " if is_negative else "" minus_str = "mīnus " if is_negative else ""
cents_str = int2word(right) if cents else "%02d" % right cents_str = int2word(right) if cents else "%02d" % right
@@ -285,8 +292,9 @@ class Num2Word_LV(object):
def to_ordinal(self, number): def to_ordinal(self, number):
raise NotImplementedError() raise NotImplementedError()
def to_currency(self, n, currency='EUR', cents=True, seperator=','): def to_currency(self, n, currency='EUR', cents=True, seperator=',',
return to_currency(n, currency, cents, seperator) prefix=False):
return to_currency(n, currency, cents, seperator, prefix)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -29,3 +29,33 @@ class Num2WordsENTest(TestCase):
self.assertEqual(num2words(12.51), "twelve point five one") self.assertEqual(num2words(12.51), "twelve point five one")
self.assertEqual(num2words(12.53), "twelve point five three") self.assertEqual(num2words(12.53), "twelve point five three")
self.assertEqual(num2words(12.59), "twelve point five nine") 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')

View File

@@ -41,7 +41,13 @@ class Num2WordsLVTest(TestCase):
self.assertEqual( self.assertEqual(
num2words('38.4', lang='lv', to='currency', seperator=' un', 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" "trīsdesmit astoņi ASV dolāri un 40 centi"
) )