Attempt at refactoring to_currency into base (#135)

* Attempt at refactoring lv to base

* Remove dead files.

* Use static props.

* Convert doctests, move utils out.

* Refactor lt

* Update and move ru doctests.

* Refactor ru.

* Refactor pl.

* Move uk doctests.

* Refactor uk.

* DRY

* Cleanup.
This commit is contained in:
Mārtiņš Šulcs
2017-11-09 17:13:01 +02:00
committed by Ernesto Rodriguez Ortiz
parent 1c699d1bb4
commit 1e954c909b
19 changed files with 983 additions and 1368 deletions

View File

@@ -18,7 +18,6 @@ from __future__ import unicode_literals
from . import lang_AR from . import lang_AR
from . import lang_EN from . import lang_EN
from . import lang_EN_GB
from . import lang_EN_IN from . import lang_EN_IN
from . import lang_FR from . import lang_FR
from . import lang_FR_CH from . import lang_FR_CH
@@ -46,7 +45,6 @@ from . import lang_SL
CONVERTER_CLASSES = { CONVERTER_CLASSES = {
'ar': lang_AR.Num2Word_AR(), 'ar': lang_AR.Num2Word_AR(),
'en': lang_EN.Num2Word_EN(), 'en': lang_EN.Num2Word_EN(),
'en_GB': lang_EN_GB.Num2Word_EN_GB(),
'en_IN': lang_EN_IN.Num2Word_EN_IN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(),
'fr': lang_FR.Num2Word_FR(), 'fr': lang_FR.Num2Word_FR(),
'fr_CH': lang_FR_CH.Num2Word_FR_CH(), 'fr_CH': lang_FR_CH.Num2Word_FR_CH(),

View File

@@ -21,9 +21,13 @@ from collections import OrderedDict
from decimal import Decimal from decimal import Decimal
from .compat import to_s from .compat import to_s
from .currency import parse_currency_parts, prefix_currency
class Num2Word_Base(object): class Num2Word_Base(object):
CURRENCY_FORMS = {}
CURRENCY_ADJECTIVES = {}
def __init__(self): def __init__(self):
self.cards = OrderedDict() self.cards = OrderedDict()
self.is_title = False self.is_title = False
@@ -243,8 +247,54 @@ class Num2Word_Base(object):
def to_year(self, value, **kwargs): def to_year(self, value, **kwargs):
return self.to_cardinal(value) return self.to_cardinal(value)
def to_currency(self, value, **kwargs): def pluralize(self, n, forms):
return self.to_cardinal(value) """
Should resolve gettext form:
http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html
"""
raise NotImplementedError
def _cents_verbose(self, number, currency):
return self.to_cardinal(number)
def to_currency(self, val, currency='EUR', cents=True, seperator=',',
adjective=False):
"""
Args:
val: Numeric value
currency (str): Currency code
cents (bool): Verbose cents
seperator (str): Cent seperator
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 if is_negative else ""
cents_str = self._cents_verbose(right, currency) \
if cents else "%02d" % right
return u'%s%s %s%s %s %s' % (
minus_str,
self.to_cardinal(left),
self.pluralize(left, cr1),
seperator,
cents_str,
self.pluralize(right, cr2)
)
def base_setup(self): def base_setup(self):
pass pass

View File

@@ -26,6 +26,8 @@ class Num2Word_EN(lang_EU.Num2Word_EU):
self.cards[10 ** n] = word + "illion" self.cards[10 ** n] = word + "illion"
def setup(self): def setup(self):
super(Num2Word_EN, self).setup()
self.negword = "minus " self.negword = "minus "
self.pointword = "point" self.pointword = "point"
self.errmsg_nornum = "Only numbers may be converted to words." self.errmsg_nornum = "Only numbers may be converted to words."
@@ -85,33 +87,3 @@ class Num2Word_EN(lang_EU.Num2Word_EU):
return self.to_cardinal(val) return self.to_cardinal(val)
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, **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)
n2w = Num2Word_EN()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
to_year = n2w.to_year
def main():
for val in [1, 11, 12, 21, 31, 33, 71, 80, 81, 91, 99, 100, 101, 102, 155,
180, 300, 308, 832, 1000, 1001, 1061, 1100, 1500, 1701, 3000,
8280, 8291, 150000, 500000, 1000000, 2000000, 2000001,
-21212121211221211111, -2.121212, -1.0000100]:
n2w.test(val)
n2w.test(13253254360678768017687001076010010122121321432104732075403270573)
for val in [1, 120, 1000, 1120, 1800, 1976, 2000, 2010, 2099, 2171]:
print(val, "is", n2w.to_currency(val))
print(val, "is", n2w.to_year(val))
if __name__ == "__main__":
main()

View File

@@ -1,53 +0,0 @@
# 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_EN import Num2Word_EN
class Num2Word_EN_EUR(Num2Word_EN):
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)
n2w = Num2Word_EN_EUR()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
to_year = n2w.to_year
to_currency = n2w.to_currency
def main():
for val in [1, 11, 12, 21, 31, 33, 71, 80, 81, 91, 99, 100, 101, 102, 155,
180, 300, 308, 832, 1000, 1001, 1061, 1100, 1500, 1701, 3000,
8280, 8291, 150000, 500000, 1000000, 2000000, 2000001,
-21212121211221211111, -2.121212, -1.0000100]:
n2w.test(val)
n2w.test(13253254360678768017687001076010010122121321432104732075403270573)
for val in [1, 120, 1000, 1120, 1800, 1976, 2000, 2010, 2099, 2171]:
print(val, "is", n2w.to_currency(val))
print(val, "is", n2w.to_year(val))
if __name__ == "__main__":
main()

View File

@@ -1,51 +0,0 @@
# 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_EN import Num2Word_EN
class Num2Word_EN_GB(Num2Word_EN):
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)
n2w = Num2Word_EN_GB()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
to_year = n2w.to_year
def main():
for val in [1, 11, 12, 21, 31, 33, 71, 80, 81, 91, 99, 100, 101, 102, 155,
180, 300, 308, 832, 1000, 1001, 1061, 1100, 1500, 1701, 3000,
8280, 8291, 150000, 500000, 1000000, 2000000, 2000001,
-21212121211221211111, -2.121212, -1.0000100]:
n2w.test(val)
n2w.test(13253254360678768017687001076010010122121321432104732075403270573)
for val in [1, 120, 1000, 1120, 1800, 1976, 2000, 2010, 2099, 2171]:
print(val, "is", n2w.to_currency(val))
print(val, "is", n2w.to_year(val))
if __name__ == "__main__":
main()

View File

@@ -18,15 +18,13 @@
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_DOLLARS = ('dollar', 'dollars')
GENERIC_CENTS = ('cent', 'cents') GENERIC_CENTS = ('cent', 'cents')
"""
Source: http://publications.europa.eu/code/en/en-5000500.htm class Num2Word_EU(Num2Word_Base):
""" CURRENCY_FORMS = {
CURRENCIES = {
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
# repalced by EUR # repalced by EUR
@@ -34,7 +32,7 @@ CURRENCIES = {
'EUR': (('euro', 'euro'), GENERIC_CENTS), 'EUR': (('euro', 'euro'), GENERIC_CENTS),
'GBP': (('pound sterling', 'pounds sterling'), ('penny', 'pence')), 'GBP': (('pound sterling', 'pounds sterling'), ('penny', 'pence')),
# replaced by EUR # replaced by EUR
'LTL': ('litas', 'litas', GENERIC_CENTS), 'LTL': (('litas', 'litas'), GENERIC_CENTS),
# replaced by EUR # replaced by EUR
'LVL': (('lat', 'lats'), ('santim', 'santims')), 'LVL': (('lat', 'lats'), ('santim', 'santims')),
'USD': (GENERIC_DOLLARS, GENERIC_CENTS), 'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
@@ -42,24 +40,17 @@ CURRENCIES = {
'SEK': (('krona', 'kronor'), ('öre', 'öre')), 'SEK': (('krona', 'kronor'), ('öre', 'öre')),
'NOK': (('krone', 'kroner'), ('øre', 'øre')), 'NOK': (('krone', 'kroner'), ('øre', 'øre')),
'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')), 'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')),
} }
PREFIXES = { CURRENCY_ADJECTIVES = {
'AUD': 'Australian', 'AUD': 'Australian',
'CAD': 'Canadian', 'CAD': 'Canadian',
'EEK': 'Estonian', 'EEK': 'Estonian',
'USD': 'US', 'USD': 'US',
'RUB': 'Russian', 'RUB': 'Russian',
'NOK': 'Norwegian', 'NOK': 'Norwegian',
} }
def pluralize(n, forms):
form = 0 if n == 1 else 1
return forms[form]
class Num2Word_EU(Num2Word_Base):
def set_high_numwords(self, high): def set_high_numwords(self, high):
max = 3 + 6 * len(high) max = 3 + 6 * len(high)
@@ -67,6 +58,10 @@ class Num2Word_EU(Num2Word_Base):
self.cards[10 ** n] = word + "illiard" self.cards[10 ** n] = word + "illiard"
self.cards[10 ** (n - 3)] = word + "illion" self.cards[10 ** (n - 3)] = word + "illion"
def pluralize(self, n, forms):
form = 0 if n == 1 else 1
return forms[form]
def base_setup(self): def base_setup(self):
lows = ["non", "oct", "sept", "sext", "quint", "quadr", "tr", "b", "m"] lows = ["non", "oct", "sept", "sext", "quint", "quadr", "tr", "b", "m"]
units = ["", "un", "duo", "tre", "quattuor", "quin", "sex", "sept", units = ["", "un", "duo", "tre", "quattuor", "quin", "sex", "sept",
@@ -75,30 +70,3 @@ class Num2Word_EU(Num2Word_Base):
"sexagint", "septuagint", "octogint", "nonagint"] "sexagint", "septuagint", "octogint", "nonagint"]
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="", **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)
)

View File

@@ -18,6 +18,8 @@
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
from .utils import get_digits, splitby3
ZERO = (u'אפס',) ZERO = (u'אפס',)
ONES = { ONES = {
@@ -70,22 +72,6 @@ THOUSANDS = {
AND = u'ו' AND = u'ו'
def splitby3(n):
length = len(n)
if length > 3:
start = length % 3
if start > 0:
yield int(n[:start])
for i in range(start, length, 3):
yield int(n[i:i + 3])
else:
yield int(n)
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
def pluralize(n, forms): def pluralize(n, forms):
# gettext implementation: # gettext implementation:
# (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2) # (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)

View File

@@ -14,165 +14,80 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA # MA 02110-1301 USA
u"""
>>> from textwrap import fill
>>> print(' '.join([str(i) for i in splitby3('1')]))
1
>>> print(' '.join([str(i) for i in splitby3('1123')]))
1 123
>>> print(' '.join([str(i) for i in splitby3('1234567890')]))
1 234 567 890
>>> print(' '.join([n2w(i) for i in range(10)]))
nulis vienas du trys keturi penki šeši septyni aštuoni devyni
>>> print(fill(' '.join([n2w(i+10) for i in range(10)])))
dešimt vienuolika dvylika trylika keturiolika penkiolika šešiolika
septyniolika aštuoniolika devyniolika
>>> print(fill(' '.join([n2w(i*10) for i in range(10)])))
nulis dešimt dvidešimt trisdešimt keturiasdešimt penkiasdešimt
šešiasdešimt septyniasdešimt aštuoniasdešimt devyniasdešimt
>>> print(n2w(100))
vienas šimtas
>>> print(n2w(101))
vienas šimtas vienas
>>> print(n2w(110))
vienas šimtas dešimt
>>> print(n2w(115))
vienas šimtas penkiolika
>>> print(n2w(123))
vienas šimtas dvidešimt trys
>>> print(n2w(1000))
vienas tūkstantis
>>> print(n2w(1001))
vienas tūkstantis vienas
>>> print(n2w(2012))
du tūkstančiai dvylika
>>> print(fill(n2w(1234567890)))
vienas milijardas du šimtai trisdešimt keturi milijonai penki šimtai
šešiasdešimt septyni tūkstančiai aštuoni šimtai devyniasdešimt
>>> print(fill(n2w(215461407892039002157189883901676)))
du šimtai penkiolika naintilijonų keturi šimtai šešiasdešimt vienas
oktilijonas keturi šimtai septyni septilijonai aštuoni šimtai
devyniasdešimt du sikstilijonai trisdešimt devyni kvintilijonai du
kvadrilijonai vienas šimtas penkiasdešimt septyni trilijonai vienas
šimtas aštuoniasdešimt devyni milijardai aštuoni šimtai
aštuoniasdešimt trys milijonai devyni šimtai vienas tūkstantis šeši
šimtai septyniasdešimt šeši
>>> print(fill(n2w(719094234693663034822824384220291)))
septyni šimtai devyniolika naintilijonų devyniasdešimt keturi
oktilijonai du šimtai trisdešimt keturi septilijonai šeši šimtai
devyniasdešimt trys sikstilijonai šeši šimtai šešiasdešimt trys
kvintilijonai trisdešimt keturi kvadrilijonai aštuoni šimtai dvidešimt
du trilijonai aštuoni šimtai dvidešimt keturi milijardai trys šimtai
aštuoniasdešimt keturi milijonai du šimtai dvidešimt tūkstančių du
šimtai devyniasdešimt vienas
# TODO: fix this:
>>> print(fill(n2w(1000000000000000000000000000000)))
naintilijonas
>>> print(to_currency(1.0, 'LTL'))
vienas litas, nulis centų
>>> print(to_currency(1234.56, 'LTL'))
vienas tūkstantis du šimtai trisdešimt keturi litai, penkiasdešimt šeši centai
>>> print(to_currency(-1251985, cents = False))
minus dvylika tūkstančių penki šimtai devyniolika eurų, 85 centai
>>> print(to_currency(1.0, 'EUR'))
vienas euras, nulis centų
>>> print(to_currency(1234.56, 'EUR'))
vienas tūkstantis du šimtai trisdešimt keturi eurai, penkiasdešimt šeši centai
"""
from __future__ import unicode_literals from __future__ import unicode_literals
from .currency import parse_currency_parts from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = (u'nulis',) ZERO = ('nulis',)
ONES = { ONES = {
1: (u'vienas',), 1: ('vienas',),
2: (u'du',), 2: ('du',),
3: (u'trys',), 3: ('trys',),
4: (u'keturi',), 4: ('keturi',),
5: (u'penki',), 5: ('penki',),
6: (u'šeši',), 6: ('šeši',),
7: (u'septyni',), 7: ('septyni',),
8: (u'aštuoni',), 8: ('aštuoni',),
9: (u'devyni',), 9: ('devyni',),
} }
TENS = { TENS = {
0: (u'dešimt',), 0: ('dešimt',),
1: (u'vienuolika',), 1: ('vienuolika',),
2: (u'dvylika',), 2: ('dvylika',),
3: (u'trylika',), 3: ('trylika',),
4: (u'keturiolika',), 4: ('keturiolika',),
5: (u'penkiolika',), 5: ('penkiolika',),
6: (u'šešiolika',), 6: ('šešiolika',),
7: (u'septyniolika',), 7: ('septyniolika',),
8: (u'aštuoniolika',), 8: ('aštuoniolika',),
9: (u'devyniolika',), 9: ('devyniolika',),
} }
TWENTIES = { TWENTIES = {
2: (u'dvidešimt',), 2: ('dvidešimt',),
3: (u'trisdešimt',), 3: ('trisdešimt',),
4: (u'keturiasdešimt',), 4: ('keturiasdešimt',),
5: (u'penkiasdešimt',), 5: ('penkiasdešimt',),
6: (u'šešiasdešimt',), 6: ('šešiasdešimt',),
7: (u'septyniasdešimt',), 7: ('septyniasdešimt',),
8: (u'aštuoniasdešimt',), 8: ('aštuoniasdešimt',),
9: (u'devyniasdešimt',), 9: ('devyniasdešimt',),
} }
HUNDRED = (u'šimtas', u'šimtai') HUNDRED = ('šimtas', 'šimtai')
THOUSANDS = { THOUSANDS = {
1: (u'tūkstantis', u'tūkstančiai', u'tūkstančių'), 1: ('tūkstantis', 'tūkstančiai', 'tūkstančių'),
2: (u'milijonas', u'milijonai', u'milijonų'), 2: ('milijonas', 'milijonai', 'milijonų'),
3: (u'milijardas', u'milijardai', u'milijardų'), 3: ('milijardas', 'milijardai', 'milijardų'),
4: (u'trilijonas', u'trilijonai', u'trilijonų'), 4: ('trilijonas', 'trilijonai', 'trilijonų'),
5: (u'kvadrilijonas', u'kvadrilijonai', u'kvadrilijonų'), 5: ('kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'),
6: (u'kvintilijonas', u'kvintilijonai', u'kvintilijonų'), 6: ('kvintilijonas', 'kvintilijonai', 'kvintilijonų'),
7: (u'sikstilijonas', u'sikstilijonai', u'sikstilijonų'), 7: ('sikstilijonas', 'sikstilijonai', 'sikstilijonų'),
8: (u'septilijonas', u'septilijonai', u'septilijonų'), 8: ('septilijonas', 'septilijonai', 'septilijonų'),
9: (u'oktilijonas', u'oktilijonai', u'oktilijonų'), 9: ('oktilijonas', 'oktilijonai', 'oktilijonų'),
10: (u'naintilijonas', u'naintilijonai', u'naintilijonų'), 10: ('naintilijonas', 'naintilijonai', 'naintilijonų'),
}
CURRENCIES = {
'LTL': ((u'litas', u'litai', u'litų'), (u'centas', u'centai', u'centų')),
'EUR': ((u'euras', u'eurai', u'eurų'), (u'centas', u'centai', u'centų')),
} }
def splitby3(n): class Num2Word_LT(Num2Word_Base):
length = len(n) CURRENCY_FORMS = {
if length > 3: 'LTL': (('litas', 'litai', 'litų'), ('centas', 'centai', 'centų')),
start = length % 3 'EUR': (('euras', 'eurai', 'eurų'), ('centas', 'centai', 'centų')),
if start > 0: }
yield int(n[:start])
for i in range(start, length, 3):
yield int(n[i:i + 3])
else:
yield int(n)
def setup(self):
self.negword = "minus"
self.pointword = "kablelis"
def get_digits(n): def set_numwords(self):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))] # @FIXME
self.cards[0] = []
def pluralize(self, n, forms):
def pluralize(n, forms):
n1, n2, n3 = get_digits(n) n1, n2, n3 = get_digits(n)
if n2 == 1 or n1 == 0 or n == 0: if n2 == 1 or n1 == 0 or n == 0:
return forms[2] return forms[2]
@@ -181,8 +96,22 @@ def pluralize(n, forms):
else: else:
return forms[1] return forms[1]
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return '%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def int2word(n): def to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, n):
if n == 0: if n == 0:
return ZERO[0] return ZERO[0]
@@ -210,41 +139,6 @@ def int2word(n):
words.append(ONES[n1][0]) words.append(ONES[n1][0])
if i > 0: if i > 0:
words.append(pluralize(x, THOUSANDS[i])) words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words) return ' '.join(words)
def n2w(n):
n = str(n).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s kablelis %s' % (int2word(int(left)), int2word(int(right)))
else:
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True):
left, right, is_negative = parse_currency_parts(n)
cr1, cr2 = CURRENCIES[currency]
minus_str = "minus " if is_negative else ""
cents_str = int2word(right) if cents else "%02d" % right
return u'%s%s %s, %s %s' % (minus_str, int2word(left),
pluralize(left, cr1),
cents_str, pluralize(right, cr2))
class Num2Word_LT(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@@ -14,92 +14,10 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA # MA 02110-1301 USA
u"""
>>> from textwrap import fill
>>> ' '.join([str(i) for i in splitby3('1')])
u'1'
>>> ' '.join([str(i) for i in splitby3('1123')])
u'1 123'
>>> ' '.join([str(i) for i in splitby3('1234567890')])
u'1 234 567 890'
>>> print(' '.join([n2w(i) for i in range(10)]))
nulle viens divi trīs četri pieci seši septiņi astoņi deviņi
>>> print(fill(' '.join([n2w(i+10) for i in range(10)])))
desmit vienpadsmit divpadsmit trīspadsmit četrpadsmit piecpadsmit
sešpadsmit septiņpadsmit astoņpadsmit deviņpadsmit
>>> print(fill(' '.join([n2w(i*10) for i in range(10)])))
nulle desmit divdesmit trīsdesmit četrdesmit piecdesmit sešdesmit
septiņdesmit astoņdesmit deviņdesmit
>>> print(n2w(100))
simts
>>> print(n2w(101))
simtu viens
>>> print(n2w(110))
simts desmit
>>> print(n2w(115))
simts piecpadsmit
>>> print(n2w(123))
simts divdesmit trīs
>>> print(n2w(1000))
tūkstotis
>>> print(n2w(1001))
tūkstotis viens
>>> print(n2w(2012))
divi tūkstoši divpadsmit
>>> print(fill(n2w(1234567890)))
miljards divi simti trīsdesmit četri miljoni pieci simti sešdesmit
septiņi tūkstoši astoņi simti deviņdesmit
>>> print(fill(n2w(215461407892039002157189883901676)))
divi simti piecpadsmit nontiljoni četri simti sešdesmit viens
oktiljons četri simti septiņi septiljoni astoņi simti deviņdesmit divi
sikstiljoni trīsdesmit deviņi kvintiljoni divi kvadriljoni simts
piecdesmit septiņi triljoni simts astoņdesmit deviņi miljardi astoņi
simti astoņdesmit trīs miljoni deviņi simti viens tūkstotis seši simti
septiņdesmit seši
>>> print(fill(n2w(719094234693663034822824384220291)))
septiņi simti deviņpadsmit nontiljoni deviņdesmit četri oktiljoni divi
simti trīsdesmit četri septiljoni seši simti deviņdesmit trīs
sikstiljoni seši simti sešdesmit trīs kvintiljoni trīsdesmit četri
kvadriljoni astoņi simti divdesmit divi triljoni astoņi simti
divdesmit četri miljardi trīs simti astoņdesmit četri miljoni divi
simti divdesmit tūkstoši divi simti deviņdesmit viens
# TODO: fix this:
# >>> print(fill(n2w(1000000000000000000000000000000)))
# nontiljons
>>> print(to_currency(1.0, 'EUR'))
viens eiro, nulle centu
>>> print(to_currency(1.0, 'LVL'))
viens lats, nulle santīmu
>>> print(to_currency(1234.56, 'EUR'))
tūkstotis divi simti trīsdesmit četri eiro, piecdesmit seši centi
>>> print(to_currency(1234.56, 'LVL'))
tūkstotis divi simti trīsdesmit četri lati, piecdesmit seši santīmi
>>> print(to_currency(10111, 'EUR', seperator=' un'))
simtu viens eiro un vienpadsmit centi
>>> print(to_currency(10121, 'LVL', seperator=' un'))
simtu viens lats un divdesmit viens santīms
>>> print(to_currency(-1251985, cents = False))
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, prefix_currency from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('nulle',) ZERO = ('nulle',)
@@ -161,15 +79,16 @@ GENERIC_KRONA = ('krona', 'kronas', 'kronu')
GENERIC_ERA = ('ēre', 'ēras', 'ēru') GENERIC_ERA = ('ēre', 'ēras', 'ēru')
""" class Num2Word_LV(Num2Word_Base):
Sadly we have a legal form (used in legal and finance documents): """
http://www.eiro.lv/files/upload/files/Eiro_rakstiba-1.pdf Sadly we have a legal form (used in legal and finance documents):
https://likumi.lv/doc.php?id=254741 http://www.eiro.lv/files/upload/files/Eiro_rakstiba-1.pdf
http://eur-lex.europa.eu/legal-content/LV/TXT/HTML/?uri=CELEX:31998R0974&from=LV https://likumi.lv/doc.php?id=254741
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 = { CURRENCY_FORMS = {
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
# repalced by EUR # repalced by EUR
@@ -180,17 +99,20 @@ CURRENCIES = {
('sterliņu mārciņa', 'sterliņu mārciņas', 'sterliņu mārciņu'), ('sterliņu mārciņa', 'sterliņu mārciņas', 'sterliņu mārciņu'),
('penss', 'pensi', 'pensu')), ('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': (GENERIC_DOLLARS, GENERIC_CENTS), 'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
'RUB': (('rublis', 'rubļi', 'rubļu'), ('kapeika', 'kapeikas', 'kapeiku')), 'RUB': (('rublis', 'rubļi', 'rubļu'),
('kapeika', 'kapeikas', 'kapeiku')),
'SEK': (GENERIC_KRONA, GENERIC_ERA), 'SEK': (GENERIC_KRONA, GENERIC_ERA),
'NOK': (GENERIC_KRONA, GENERIC_ERA), 'NOK': (GENERIC_KRONA, GENERIC_ERA),
'PLN': (('zlots', 'zloti', 'zlotu'), ('grasis', 'graši', 'grašu')), 'PLN': (('zlots', 'zloti', 'zlotu'),
} ('grasis', 'graši', 'grašu')),
}
PREFIXES = { CURRENCY_ADJECTIVES = {
'AUD': 'Austrālijas', 'AUD': 'Austrālijas',
'CAD': 'Kanādas', 'CAD': 'Kanādas',
'EEK': 'Igaunijas', 'EEK': 'Igaunijas',
@@ -198,31 +120,36 @@ PREFIXES = {
'RUB': 'Kreivijas', 'RUB': 'Kreivijas',
'SEK': 'Zviedrijas', 'SEK': 'Zviedrijas',
'NOK': 'Norvēģijas', 'NOK': 'Norvēģijas',
} }
def setup(self):
self.negword = "mīnus"
self.pointword = "komats"
def splitby3(n): def set_numwords(self):
length = len(n) # @FIXME
if length > 3: self.cards[0] = []
start = length % 3
if start > 0: def to_cardinal(self, number):
yield int(n[:start]) n = str(number).replace(',', '.')
for i in range(start, length, 3): if '.' in n:
yield int(n[i:i+3]) left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else: else:
yield int(n) return self._int2word(int(n))
def pluralize(self, n, forms):
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
def pluralize(n, forms):
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2 form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
return forms[form] return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def int2word(n): def _int2word(self, n):
if n == 0: if n == 0:
return ZERO[0] return ZERO[0]
@@ -251,52 +178,6 @@ def int2word(n):
words.append(ONES[n1][0]) words.append(ONES[n1][0])
if i > 0 and x != 0: if i > 0 and x != 0:
words.append(pluralize(x, THOUSANDS[i])) words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words) return ' '.join(words)
def n2w(n):
n = str(n).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s komats %s' % (int2word(int(left)), int2word(int(right)))
else:
return int2word(int(n))
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
return u'%s%s %s%s %s %s' % (
minus_str,
int2word(left),
pluralize(left, cr1),
seperator,
cents_str,
pluralize(right, cr2)
)
class Num2Word_LV(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
def to_currency(self, n, currency='EUR', cents=True, seperator=',',
prefix=False):
return to_currency(n, currency, cents, seperator, prefix)
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@@ -14,188 +14,106 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA # MA 02110-1301 USA
u"""
>>> from textwrap import fill
>>> ' '.join([str(i) for i in splitby3('1')])
'1'
>>> ' '.join([str(i) for i in splitby3('1123')])
'1 123'
>>> ' '.join([str(i) for i in splitby3('1234567890')])
'1 234 567 890'
>>> print(' '.join([n2w(i) for i in range(10)]))
zero jeden dwa trzy cztery pięć sześć siedem osiem dziewięć
>>> print(fill(' '.join([n2w(i+10) for i in range(10)])))
dziesięć jedenaście dwanaście trzynaście czternaście piętnaście
szesnaście siedemnaście osiemnaście dziewiętnaście
>>> print(fill(' '.join([n2w(i*10) for i in range(10)])))
zero dziesięć dwadzieścia trzydzieści czterdzieści pięćdziesiąt
sześćdziesiąt siedemdziesiąt osiemdziesiąt dziewięćdzisiąt
>>> print(n2w(100))
sto
>>> print(n2w(101))
sto jeden
>>> print(n2w(110))
sto dziesięć
>>> print(n2w(115))
sto piętnaście
>>> print(n2w(123))
sto dwadzieścia trzy
>>> print(n2w(1000))
tysiąc
>>> print(n2w(1001))
tysiąc jeden
>>> print(n2w(2012))
dwa tysiące dwanaście
>>> print(n2w(12519.85))
dwanaście tysięcy pięćset dziewiętnaście przecinek osiemdziesiąt pięć
>>> print(n2w(123.50))
sto dwadzieścia trzy przecinek pięć
>>> print(fill(n2w(1234567890)))
miliard dwieście trzydzieści cztery miliony pięćset sześćdziesiąt
siedem tysięcy osiemset dziewięćdzisiąt
>>> print(fill(n2w(215461407892039002157189883901676)))
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 dwa biliardy sto
pięćdziesiąt siedem bilionów sto osiemdziesiąt dziewięć miliardów
osiemset osiemdziesiąt trzy miliony dziewęćset jeden tysięcy sześćset
siedemdziesiąt sześć
>>> print(fill(n2w(719094234693663034822824384220291)))
siedemset dziewiętnaście kwintylionów dziewięćdzisiąt cztery
kwadryliardy dwieście trzydzieści cztery kwadryliony sześćset
dziewięćdzisią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
>>> print(to_currency(1.0, 'EUR'))
jeden euro, zero centów
>>> print(to_currency(1.0, 'PLN'))
jeden złoty, zero groszy
>>> print(to_currency(1234.56, 'EUR'))
tysiąc dwieście trzydzieści cztery euro, pięćdziesiąt sześć centów
>>> print(to_currency(1234.56, 'PLN'))
tysiąc dwieście trzydzieści cztery złote, pięćdziesiąt sześć groszy
>>> print(to_currency(10111, 'EUR', seperator=' i'))
sto jeden euro i jedenaście centów
>>> print(to_currency(10121, 'PLN', seperator=' i'))
sto jeden złotych i dwadzieścia jeden groszy
>>> print(to_currency(-1251985, cents = False))
minus dwanaście tysięcy pięćset dziewiętnaście euro, 85 centów
>>> print(to_currency(123.50, 'PLN', seperator=' i'))
sto dwadzieścia trzy złote i pięćdziesiąt groszy
"""
from __future__ import unicode_literals from __future__ import unicode_literals
from .currency import parse_currency_parts from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = (u'zero',) ZERO = ('zero',)
ONES = { ONES = {
1: (u'jeden',), 1: ('jeden',),
2: (u'dwa',), 2: ('dwa',),
3: (u'trzy',), 3: ('trzy',),
4: (u'cztery',), 4: ('cztery',),
5: (u'pięć',), 5: ('pięć',),
6: (u'sześć',), 6: ('sześć',),
7: (u'siedem',), 7: ('siedem',),
8: (u'osiem',), 8: ('osiem',),
9: (u'dziewięć',), 9: ('dziewięć',),
} }
TENS = { TENS = {
0: (u'dziesięć',), 0: ('dziesięć',),
1: (u'jedenaście',), 1: ('jedenaście',),
2: (u'dwanaście',), 2: ('dwanaście',),
3: (u'trzynaście',), 3: ('trzynaście',),
4: (u'czternaście',), 4: ('czternaście',),
5: (u'piętnaście',), 5: ('piętnaście',),
6: (u'szesnaście',), 6: ('szesnaście',),
7: (u'siedemnaście',), 7: ('siedemnaście',),
8: (u'osiemnaście',), 8: ('osiemnaście',),
9: (u'dziewiętnaście',), 9: ('dziewiętnaście',),
} }
TWENTIES = { TWENTIES = {
2: (u'dwadzieścia',), 2: ('dwadzieścia',),
3: (u'trzydzieści',), 3: ('trzydzieści',),
4: (u'czterdzieści',), 4: ('czterdzieści',),
5: (u'pięćdziesiąt',), 5: ('pięćdziesiąt',),
6: (u'sześćdziesiąt',), 6: ('sześćdziesiąt',),
7: (u'siedemdziesiąt',), 7: ('siedemdziesiąt',),
8: (u'osiemdziesiąt',), 8: ('osiemdziesiąt',),
9: (u'dziewięćdzisiąt',), 9: ('dziewięćdzisiąt',),
} }
HUNDREDS = { HUNDREDS = {
1: (u'sto',), 1: ('sto',),
2: (u'dwieście',), 2: ('dwieście',),
3: (u'trzysta',), 3: ('trzysta',),
4: (u'czterysta',), 4: ('czterysta',),
5: (u'pięćset',), 5: ('pięćset',),
6: (u'sześćset',), 6: ('sześćset',),
7: (u'siedemset',), 7: ('siedemset',),
8: (u'osiemset',), 8: ('osiemset',),
9: (u'dziewęćset',), 9: ('dziewęćset',),
} }
THOUSANDS = { THOUSANDS = {
1: (u'tysiąc', u'tysiące', u'tysięcy'), # 10^3 1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3
2: (u'milion', u'miliony', u'milionów'), # 10^6 2: ('milion', 'miliony', 'milionów'), # 10^6
3: (u'miliard', u'miliardy', u'miliardów'), # 10^9 3: ('miliard', 'miliardy', 'miliardów'), # 10^9
4: (u'bilion', u'biliony', u'bilionów'), # 10^12 4: ('bilion', 'biliony', 'bilionów'), # 10^12
5: (u'biliard', u'biliardy', u'biliardów'), # 10^15 5: ('biliard', 'biliardy', 'biliardów'), # 10^15
6: (u'trylion', u'tryliony', u'trylionów'), # 10^18 6: ('trylion', 'tryliony', 'trylionów'), # 10^18
7: (u'tryliard', u'tryliardy', u'tryliardów'), # 10^21 7: ('tryliard', 'tryliardy', 'tryliardów'), # 10^21
8: (u'kwadrylion', u'kwadryliony', u'kwadrylionów'), # 10^24 8: ('kwadrylion', 'kwadryliony', 'kwadrylionów'), # 10^24
9: (u'kwaryliard', u'kwadryliardy', u'kwadryliardów'), # 10^27 9: ('kwaryliard', 'kwadryliardy', 'kwadryliardów'), # 10^27
10: (u'kwintylion', u'kwintyliony', u'kwintylionów'), # 10^30 10: ('kwintylion', 'kwintyliony', 'kwintylionów'), # 10^30
} }
CURRENCIES = {
class Num2Word_PL(Num2Word_Base):
CURRENCY_FORMS = {
'PLN': ( 'PLN': (
(u'złoty', u'złote', u'złotych'), (u'grosz', u'grosze', u'groszy') ('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy')
), ),
'EUR': ( 'EUR': (
(u'euro', u'euro', u'euro'), (u'cent', u'centy', u'centów') ('euro', 'euro', 'euro'), ('cent', 'centy', 'centów')
), ),
} }
def setup(self):
self.negword = "minus"
self.pointword = "przecinek"
def splitby3(n): def set_numwords(self):
length = len(n) # @FIXME
if length > 3: self.cards[0] = []
start = length % 3
if start > 0: def to_cardinal(self, number):
yield int(n[:start]) n = str(number).replace(',', '.')
for i in range(start, length, 3): if '.' in n:
yield int(n[i:i + 3]) left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else: else:
yield int(n) return self._int2word(int(n))
def pluralize(self, n, forms):
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
def pluralize(n, forms):
if n == 1: if n == 1:
form = 0 form = 0
elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20): elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20):
@@ -204,8 +122,10 @@ def pluralize(n, forms):
form = 2 form = 2
return forms[form] return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def int2word(n): def _int2word(self, n):
if n == 0: if n == 0:
return ZERO[0] return ZERO[0]
@@ -228,49 +148,6 @@ def int2word(n):
words.append(ONES[n1][0]) words.append(ONES[n1][0])
if i > 0: if i > 0:
words.append(pluralize(x, THOUSANDS[i])) words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words) return ' '.join(words)
def n2w(n):
n = str(n).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s przecinek %s' % (int2word(int(left)), int2word(int(right)))
else:
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, seperator=','):
left, right, is_negative = parse_currency_parts(n)
cr1, cr2 = CURRENCIES[currency]
minus_str = "minus " if is_negative else ""
cents_str = int2word(right) if cents else "%02d" % right
return u'%s%s %s%s %s %s' % (
minus_str,
int2word(left),
pluralize(left, cr1),
seperator,
cents_str,
pluralize(right, cr2)
)
class Num2Word_PL(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
def to_currency(self, n, currency='EUR', cents=True, seperator=','):
return to_currency(n, currency, cents, seperator)
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@@ -14,199 +14,118 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA # MA 02110-1301 USA
u"""
>>> from textwrap import fill
>>> ' '.join([str(i) for i in splitby3('1')])
'1'
>>> ' '.join([str(i) for i in splitby3('1123')])
'1 123'
>>> ' '.join([str(i) for i in splitby3('1234567890')])
'1 234 567 890'
>>> print(' '.join([n2w(i) for i in range(10)]))
ноль один два три четыре пять шесть семь восемь девять
>>> print(fill(' '.join([n2w(i+10) for i in range(10)])))
десять одиннадцать двенадцать тринадцать четырнадцать пятнадцать
шестнадцать семнадцать восемнадцать девятнадцать
>>> print(fill(' '.join([n2w(i*10) for i in range(10)])))
ноль десять двадцать тридцать сорок пятьдесят шестьдесят семьдесят
восемьдесят девяносто
>>> print(n2w(100))
сто
>>> print(n2w(101))
сто один
>>> print(n2w(110))
сто десять
>>> print(n2w(115))
сто пятнадцать
>>> print(n2w(123))
сто двадцать три
>>> print(n2w(1000))
тысяча
>>> print(n2w(1001))
тысяча один
>>> print(n2w(2012))
две тысячи двенадцать
>>> print(n2w(12519.85))
двенадцать тысяч пятьсот девятнадцать запятая восемьдесят пять
>>> print(fill(n2w(1234567890)))
миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч
восемьсот девяносто
>>> print(fill(n2w(215461407892039002157189883901676)))
двести пятнадцать нониллионов четыреста шестьдесят один октиллион
четыреста семь септиллионов восемьсот девяносто два секстиллиона
тридцать девять квинтиллионов два квадриллиона сто пятьдесят семь
триллионов сто восемьдесят девять миллиардов восемьсот восемьдесят три
миллиона девятьсот одна тысяча шестьсот семьдесят шесть
>>> print(fill(n2w(719094234693663034822824384220291)))
семьсот девятнадцать нониллионов девяносто четыре октиллиона двести
тридцать четыре септиллиона шестьсот девяносто три секстиллиона
шестьсот шестьдесят три квинтиллиона тридцать четыре квадриллиона
восемьсот двадцать два триллиона восемьсот двадцать четыре миллиарда
триста восемьдесят четыре миллиона двести двадцать тысяч двести
девяносто один
>>> print(to_currency(1.0, 'EUR'))
один евро, ноль центов
>>> print(to_currency(1.0, 'RUB'))
один рубль, ноль копеек
>>> print(to_currency(1234.56, 'EUR'))
тысяча двести тридцать четыре евро, пятьдесят шесть центов
>>> print(to_currency(1234.56, 'RUB'))
тысяча двести тридцать четыре рубля, пятьдесят шесть копеек
>>> print(to_currency(10111, 'EUR', seperator=u' и'))
сто один евро и одиннадцать центов
>>> print(to_currency(10121, 'RUB', seperator=u' и'))
сто один рубль и двадцать одна копейка
>>> print(to_currency(10122, 'RUB', seperator=u' и'))
сто один рубль и двадцать две копейки
>>> print(to_currency(10121, 'EUR', seperator=u' и'))
сто один евро и двадцать один цент
>>> print(to_currency(-1251985, cents = False))
минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов
"""
from __future__ import unicode_literals from __future__ import unicode_literals
from .currency import parse_currency_parts from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = (u'ноль',) ZERO = ('ноль',)
ONES_FEMININE = { ONES_FEMININE = {
1: (u'одна',), 1: ('одна',),
2: (u'две',), 2: ('две',),
3: (u'три',), 3: ('три',),
4: (u'четыре',), 4: ('четыре',),
5: (u'пять',), 5: ('пять',),
6: (u'шесть',), 6: ('шесть',),
7: (u'семь',), 7: ('семь',),
8: (u'восемь',), 8: ('восемь',),
9: (u'девять',), 9: ('девять',),
} }
ONES = { ONES = {
1: (u'один',), 1: ('один',),
2: (u'два',), 2: ('два',),
3: (u'три',), 3: ('три',),
4: (u'четыре',), 4: ('четыре',),
5: (u'пять',), 5: ('пять',),
6: (u'шесть',), 6: ('шесть',),
7: (u'семь',), 7: ('семь',),
8: (u'восемь',), 8: ('восемь',),
9: (u'девять',), 9: ('девять',),
} }
TENS = { TENS = {
0: (u'десять',), 0: ('десять',),
1: (u'одиннадцать',), 1: ('одиннадцать',),
2: (u'двенадцать',), 2: ('двенадцать',),
3: (u'тринадцать',), 3: ('тринадцать',),
4: (u'четырнадцать',), 4: ('четырнадцать',),
5: (u'пятнадцать',), 5: ('пятнадцать',),
6: (u'шестнадцать',), 6: ('шестнадцать',),
7: (u'семнадцать',), 7: ('семнадцать',),
8: (u'восемнадцать',), 8: ('восемнадцать',),
9: (u'девятнадцать',), 9: ('девятнадцать',),
} }
TWENTIES = { TWENTIES = {
2: (u'двадцать',), 2: ('двадцать',),
3: (u'тридцать',), 3: ('тридцать',),
4: (u'сорок',), 4: ('сорок',),
5: (u'пятьдесят',), 5: ('пятьдесят',),
6: (u'шестьдесят',), 6: ('шестьдесят',),
7: (u'семьдесят',), 7: ('семьдесят',),
8: (u'восемьдесят',), 8: ('восемьдесят',),
9: (u'девяносто',), 9: ('девяносто',),
} }
HUNDREDS = { HUNDREDS = {
1: (u'сто',), 1: ('сто',),
2: (u'двести',), 2: ('двести',),
3: (u'триста',), 3: ('триста',),
4: (u'четыреста',), 4: ('четыреста',),
5: (u'пятьсот',), 5: ('пятьсот',),
6: (u'шестьсот',), 6: ('шестьсот',),
7: (u'семьсот',), 7: ('семьсот',),
8: (u'восемьсот',), 8: ('восемьсот',),
9: (u'девятьсот',), 9: ('девятьсот',),
} }
THOUSANDS = { THOUSANDS = {
1: (u'тысяча', u'тысячи', u'тысяч'), # 10^3 1: ('тысяча', 'тысячи', 'тысяч'), # 10^3
2: (u'миллион', u'миллиона', u'миллионов'), # 10^6 2: ('миллион', 'миллиона', 'миллионов'), # 10^6
3: (u'миллиард', u'миллиарда', u'миллиардов'), # 10^9 3: ('миллиард', 'миллиарда', 'миллиардов'), # 10^9
4: (u'триллион', u'триллиона', u'триллионов'), # 10^12 4: ('триллион', 'триллиона', 'триллионов'), # 10^12
5: (u'квадриллион', u'квадриллиона', u'квадриллионов'), # 10^15 5: ('квадриллион', 'квадриллиона', 'квадриллионов'), # 10^15
6: (u'квинтиллион', u'квинтиллиона', u'квинтиллионов'), # 10^18 6: ('квинтиллион', 'квинтиллиона', 'квинтиллионов'), # 10^18
7: (u'секстиллион', u'секстиллиона', u'секстиллионов'), # 10^21 7: ('секстиллион', 'секстиллиона', 'секстиллионов'), # 10^21
8: (u'септиллион', u'септиллиона', u'септиллионов'), # 10^24 8: ('септиллион', 'септиллиона', 'септиллионов'), # 10^24
9: (u'октиллион', u'октиллиона', u'октиллионов'), # 10^27 9: ('октиллион', 'октиллиона', 'октиллионов'), # 10^27
10: (u'нониллион', u'нониллиона', u'нониллионов'), # 10^30 10: ('нониллион', 'нониллиона', 'нониллионов'), # 10^30
} }
CURRENCIES = {
class Num2Word_RU(Num2Word_Base):
CURRENCY_FORMS = {
'RUB': ( 'RUB': (
(u'рубль', u'рубля', u'рублей'), (u'копейка', u'копейки', u'копеек') ('рубль', 'рубля', 'рублей'), ('копейка', 'копейки', 'копеек')
), ),
'EUR': ( 'EUR': (
(u'евро', u'евро', u'евро'), (u'цент', u'цента', u'центов') ('евро', 'евро', 'евро'), ('цент', 'цента', 'центов')
), ),
} }
def setup(self):
self.negword = "минус"
self.pointword = "запятая"
def splitby3(n): def set_numwords(self):
length = len(n) # @FIXME
if length > 3: self.cards[0] = []
start = length % 3
if start > 0: def to_cardinal(self, number):
yield int(n[:start]) n = str(number).replace(',', '.')
for i in range(start, length, 3): if '.' in n:
yield int(n[i:i + 3]) left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else: else:
yield int(n) return self._int2word(int(n))
def pluralize(self, n, forms):
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
def pluralize(n, forms):
if n % 100 < 10 or n % 100 > 20: if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1: if n % 10 == 1:
form = 0 form = 0
@@ -218,10 +137,15 @@ def pluralize(n, forms):
form = 2 form = 2
return forms[form] return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def int2word(n, feminine=False): def _cents_verbose(self, number, currency):
return self._int2word(number, currency == 'RUB')
def _int2word(self, n, feminine=False):
if n < 0: if n < 0:
return ' '.join([u'минус', int2word(abs(n))]) return ' '.join([self.negword, self._int2word(abs(n))])
if n == 0: if n == 0:
return ZERO[0] return ZERO[0]
@@ -246,54 +170,6 @@ def int2word(n, feminine=False):
words.append(ones[n1][0]) words.append(ones[n1][0])
if i > 0 and x != 0: if i > 0 and x != 0:
words.append(pluralize(x, THOUSANDS[i])) words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words) return ' '.join(words)
def n2w(n):
n = str(n).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s запятая %s' % (int2word(int(left)), int2word(int(right)))
else:
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, seperator=','):
left, right, is_negative = parse_currency_parts(n)
cr1, cr2 = CURRENCIES[currency]
minus_str = "минус " if is_negative else ""
if cents:
cents_feminine = currency == 'RUB'
cents_str = int2word(right, cents_feminine)
else:
cents_str = "%02d" % right
return u'%s%s %s%s %s %s' % (
minus_str,
int2word(left),
pluralize(left, cr1),
seperator,
cents_str,
pluralize(right, cr2)
)
class Num2Word_RU(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
def to_currency(self, n, currency='EUR', cents=True, seperator=','):
return to_currency(n, currency, cents, seperator)
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@@ -14,202 +14,119 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA # MA 02110-1301 USA
u"""
>>> from textwrap import fill
>>> ' '.join([str(i) for i in splitby3('1')])
'1'
>>> ' '.join([str(i) for i in splitby3('1123')])
'1 123'
>>> ' '.join([str(i) for i in splitby3('1234567890')])
'1 234 567 890'
>>> print(' '.join([n2w(i) for i in range(10)]))
нуль один два три чотири п'ять шiсть сiмь вiсiм дев'ять
>>> print(fill(' '.join([n2w(i+10) for i in range(10)])))
десять одинадцять дванадцять тринадцять чотирнадцять п'ятнадцять
шiстнадцять сiмнадцять вiсiмнадцять дев'ятнадцять
>>> print(fill(' '.join([n2w(i*10) for i in range(10)])))
нуль десять двадцять тридцять сорок п'ятдесят шiстдесят сiмдесят
вiсiмдесят дев'яносто
>>> print(n2w(100))
сто
>>> print(n2w(101))
сто один
>>> print(n2w(110))
сто десять
>>> print(n2w(115))
сто п'ятнадцять
>>> print(n2w(123))
сто двадцять три
>>> print(n2w(1000))
тисяча
>>> print(n2w(1001))
тисяча один
>>> print(n2w(2012))
двi тисячi дванадцять
>>> print(n2w(12519.85))
дванадцять тисяч п'ятсот дев'ятнадцять кома вiсiмдесят п'ять
>>> print(fill(n2w(1234567890)))
мiльярд двiстi тридцать чотири мiльйона п'ятсот шiстдесят сiмь тисяч
вiссот дев'яносто
>>> print(fill(n2w(215461407892039002157189883901676)))
двiстi п'ятнадцять нонiльйонiв чотириста шiстдесят один октильйон
чотириста ссептильйонiв вiссот дев'яносто два секстильйони
тридцять дев'ять квiнтильйонiв два квадрильйони сто п'ятдесят с
трильйонiв сто вiсiмдесят дев'ять мiльярдiв вiссот вiсiмдесят три
мiльйона дев'ятсот одна тисяча шiстсот сiмдесят шiсть
>>> print(fill(n2w(719094234693663034822824384220291)))
ссот дев'ятнадцять нонiльйонiв дев'яносто чотири октильйони двiстi
тридцять чотири септильйони шiстсот дев'яносто три секстильйони
шiстсот шiстдесят три квiнтильйони тридцять чотири квадрильйони
вiссот двадцять два трильйони вiссот двадцять чотири мiльярди
триста вiсiмдесят чотири мiльйона двiстi двадцять тисяч двiстi
дев'яносто один
>>> print(to_currency(1.0, 'EUR'))
один євро, нуль центiв
>>> print(to_currency(1.0, 'UAH'))
одна гривня, нуль копiйок
>>> print(to_currency(1234.56, 'EUR'))
тисяча двiстi тридцять чотири євро, п'ятдесят шiсть центiв
>>> print(to_currency(1234.56, 'UAH'))
тисяча двiстi тридцять чотири гривнi, п'ятдесят шiсть копiйок
>>> print(to_currency(10111, 'EUR', seperator=u' та'))
сто один євро та одинадцять центiв
>>> print(to_currency(10121, 'UAH', seperator=u' та'))
сто одна гривня та двадцять одна копiйка
>>> print(to_currency(10122, 'UAH', seperator=u' та'))
сто одна гривня та двадцять одна копiйка
>>> print(to_currency(10121, 'EUR', seperator=u' та'))
сто один євро та двадцять один цент
>>> print(to_currency(-1251985, cents = False))
мiнус дванадцять тисяч п'ятьсот дев'ятнадцять євро, 85 центiв
"""
from __future__ import unicode_literals from __future__ import unicode_literals
from .currency import parse_currency_parts from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = (u'нуль',) ZERO = ('нуль',)
ONES_FEMININE = { ONES_FEMININE = {
1: (u'одна',), 1: ('одна',),
2: (u'двi',), 2: ('двi',),
3: (u'три',), 3: ('три',),
4: (u'чотири',), 4: ('чотири',),
5: (u'п\'ять',), 5: ('п\'ять',),
6: (u'шiсть',), 6: ('шiсть',),
7: (u'с',), 7: ('с',),
8: (u'вiс',), 8: ('вiс',),
9: (u'дев\'ять',), 9: ('дев\'ять',),
} }
ONES = { ONES = {
1: (u'один',), 1: ('один',),
2: (u'два',), 2: ('два',),
3: (u'три',), 3: ('три',),
4: (u'чотири',), 4: ('чотири',),
5: (u'п\'ять',), 5: ('п\'ять',),
6: (u'шiсть',), 6: ('шiсть',),
7: (u'с',), 7: ('с',),
8: (u'вiс',), 8: ('вiс',),
9: (u'дев\'ять',), 9: ('дев\'ять',),
} }
TENS = { TENS = {
0: (u'десять',), 0: ('десять',),
1: (u'одинадцять',), 1: ('одинадцять',),
2: (u'дванадцять',), 2: ('дванадцять',),
3: (u'тринадцять',), 3: ('тринадцять',),
4: (u'чотирнадцять',), 4: ('чотирнадцять',),
5: (u'п\'ятнадцять',), 5: ('п\'ятнадцять',),
6: (u'шiстнадцять',), 6: ('шiстнадцять',),
7: (u'сiмнадцять',), 7: ('сiмнадцять',),
8: (u'вiсiмнадцять',), 8: ('вiсiмнадцять',),
9: (u'дев\'ятнадцять',), 9: ('дев\'ятнадцять',),
} }
TWENTIES = { TWENTIES = {
2: (u'двадцять',), 2: ('двадцять',),
3: (u'тридцять',), 3: ('тридцять',),
4: (u'сорок',), 4: ('сорок',),
5: (u'п\'ятдесят',), 5: ('п\'ятдесят',),
6: (u'шiстдесят',), 6: ('шiстдесят',),
7: (u'сiмдесят',), 7: ('сiмдесят',),
8: (u'вiсiмдесят',), 8: ('вiсiмдесят',),
9: (u'дев\'яносто',), 9: ('дев\'яносто',),
} }
HUNDREDS = { HUNDREDS = {
1: (u'сто',), 1: ('сто',),
2: (u'двiстi',), 2: ('двiстi',),
3: (u'триста',), 3: ('триста',),
4: (u'чотириста',), 4: ('чотириста',),
5: (u'п\'ятсот',), 5: ('п\'ятсот',),
6: (u'шiстсот',), 6: ('шiстсот',),
7: (u'ссот',), 7: ('ссот',),
8: (u'вiссот',), 8: ('вiссот',),
9: (u'дев\'ятсот',), 9: ('дев\'ятсот',),
} }
THOUSANDS = { THOUSANDS = {
1: (u'тисяча', u'тисячi', u'тисяч'), # 10^3 1: ('тисяча', 'тисячi', 'тисяч'), # 10^3
2: (u'мiльйон', u'мiльйони', u'мiльйонiв'), # 10^6 2: ('мiльйон', 'мiльйони', 'мiльйонiв'), # 10^6
3: (u'мiльярд', u'мiльярди', u'мiльярдiв'), # 10^9 3: ('мiльярд', 'мiльярди', 'мiльярдiв'), # 10^9
4: (u'трильйон', u'трильйони', u'трильйонiв'), # 10^12 4: ('трильйон', 'трильйони', 'трильйонiв'), # 10^12
5: (u'квадрильйон', u'квадрильйони', u'квадрильйонiв'), # 10^15 5: ('квадрильйон', 'квадрильйони', 'квадрильйонiв'), # 10^15
6: (u'квiнтильйон', u'квiнтильйони', u'квiнтильйонiв'), # 10^18 6: ('квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'), # 10^18
7: (u'секстильйон', u'секстильйони', u'секстильйонiв'), # 10^21 7: ('секстильйон', 'секстильйони', 'секстильйонiв'), # 10^21
8: (u'септильйон', u'септильйони', u'септильйонiв'), # 10^24 8: ('септильйон', 'септильйони', 'септильйонiв'), # 10^24
9: (u'октильйон', u'октильйони', u'октильйонiв'), # 10^27 9: ('октильйон', 'октильйони', 'октильйонiв'), # 10^27
10: (u'нонiльйон', u'нонiльйони', u'нонiльйонiв'), # 10^30 10: ('нонiльйон', 'нонiльйони', 'нонiльйонiв'), # 10^30
} }
CURRENCIES = {
class Num2Word_UK(Num2Word_Base):
CURRENCY_FORMS = {
'UAH': ( 'UAH': (
(u'гривня', u'гривнi', u'гривень'), ('гривня', 'гривнi', 'гривень'),
(u'копiйка', u'копiйки', u'копiйок') ('копiйка', 'копiйки', 'копiйок')
), ),
'EUR': ( 'EUR': (
(u'евро', u'евро', u'евро'), (u'цент', u'центи', u'центiв') ('евро', 'евро', 'евро'), ('цент', 'центи', 'центiв')
), ),
} }
def setup(self):
self.negword = "мiнус"
self.pointword = "кома"
def splitby3(n): def set_numwords(self):
length = len(n) # @FIXME
if length > 3: self.cards[0] = []
start = length % 3
if start > 0: def to_cardinal(self, number):
yield int(n[:start]) n = str(number).replace(',', '.')
for i in range(start, length, 3): if '.' in n:
yield int(n[i:i + 3]) left, right = n.split('.')
return '%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else: else:
yield int(n) return self._int2word(int(n))
def pluralize(self, n, forms):
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
def pluralize(n, forms):
# form = 0 if n==1 else 1 if (n % 10 > 1 and n % 10 < 5 and (n % 100 < 10
# or n % 100 > 20)) else 2
if n % 100 < 10 or n % 100 > 20: if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1: if n % 10 == 1:
form = 0 form = 0
@@ -222,10 +139,9 @@ def pluralize(n, forms):
return forms[form] return forms[form]
def _int2word(self, n, feminine=True):
def int2word(n, feminine=True):
if n < 0: if n < 0:
return ' '.join([u'мiнус', int2word(abs(n))]) return ' '.join([self.negword, self._int2word(abs(n))])
if n == 0: if n == 0:
return ZERO[0] return ZERO[0]
@@ -251,54 +167,12 @@ def int2word(n, feminine=True):
words.append(ones[n1][0]) words.append(ones[n1][0])
if i > 0 and ((n1 + n2 + n3) > 0): if i > 0 and ((n1 + n2 + n3) > 0):
words.append(pluralize(x, THOUSANDS[i])) words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words) return ' '.join(words)
def _cents_verbose(self, number, currency):
def n2w(n): return self._int2word(number, currency == 'UAH')
n = str(n).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s кома %s' % (int2word(int(left)), int2word(int(right)))
else:
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, seperator=','):
left, right, is_negative = parse_currency_parts(n)
cr1, cr2 = CURRENCIES[currency]
minus_str = "мiнус " if is_negative else ""
if cents:
cents_feminine = currency == 'UAH'
cents_str = int2word(right, cents_feminine)
else:
cents_str = "%02d" % right
return u'%s%s %s%s %s %s' % (
minus_str,
int2word(left),
pluralize(left, cr1),
seperator,
cents_str,
pluralize(right, cr2)
)
class Num2Word_UK(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number): def to_ordinal(self, number):
raise NotImplementedError() raise NotImplementedError()
def to_currency(self, n, currency='EUR', cents=True, seperator=','):
return to_currency(n, currency, cents, seperator)
if __name__ == '__main__':
import doctest
doctest.testmod()

14
num2words/utils.py Normal file
View File

@@ -0,0 +1,14 @@
def splitby3(n):
length = len(n)
if length > 3:
start = length % 3
if start > 0:
yield int(n[:start])
for i in range(start, length, 3):
yield int(n[i:i+3])
else:
yield int(n)
def get_digits(n):
return [int(x) for x in reversed(list(('%03d' % n)[-3:]))]

View File

@@ -50,7 +50,7 @@ class Num2WordsENTest(TestCase):
self.assertEqual( self.assertEqual(
num2words('4778.00', lang='en', to='currency', seperator=' and', num2words('4778.00', lang='en', to='currency', seperator=' and',
cents=True, currency='USD', prefix=True), cents=True, currency='USD', adjective=True),
'four thousand, seven hundred and seventy-eight US dollars' 'four thousand, seven hundred and seventy-eight US dollars'
' and zero cents') ' and zero cents')

80
tests/test_lt.py Normal file
View File

@@ -0,0 +1,80 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
from unittest import TestCase
from num2words import num2words
class Num2WordsLTTest(TestCase):
def test_to_cardinal(self):
self.assertEqual(num2words(100, lang='lt'), 'vienas šimtas')
self.assertEqual(num2words(101, lang='lt'), 'vienas šimtas vienas')
self.assertEqual(num2words(110, lang='lt'), 'vienas šimtas dešimt')
self.assertEqual(num2words(115, lang='lt'),
'vienas šimtas penkiolika')
self.assertEqual(num2words(123, lang='lt'),
'vienas šimtas dvidešimt trys')
self.assertEqual(num2words(1000, lang='lt'), 'vienas tūkstantis')
self.assertEqual(num2words(1001, lang='lt'),
'vienas tūkstantis vienas')
self.assertEqual(num2words(2012, lang='lt'),
'du tūkstančiai dvylika')
self.assertEqual(
num2words(1234567890, lang='lt'),
"vienas milijardas du šimtai trisdešimt keturi milijonai "
"penki šimtai šešiasdešimt septyni tūkstančiai aštuoni šimtai "
"devyniasdešimt")
self.assertEqual(
num2words(215461407892039002157189883901676, lang='lt'),
"du šimtai penkiolika naintilijonų keturi šimtai šešiasdešimt "
"vienas oktilijonas keturi šimtai septyni septilijonai aštuoni "
"šimtai devyniasdešimt du sikstilijonai trisdešimt devyni "
"kvintilijonai du kvadrilijonai vienas šimtas penkiasdešimt "
"septyni trilijonai vienas šimtas aštuoniasdešimt devyni "
"milijardai aštuoni šimtai aštuoniasdešimt trys milijonai "
"devyni šimtai vienas tūkstantis šeši šimtai "
"septyniasdešimt šeši")
self.assertEqual(
num2words(719094234693663034822824384220291, lang='lt'),
"septyni šimtai devyniolika naintilijonų devyniasdešimt keturi "
"oktilijonai du šimtai trisdešimt keturi septilijonai šeši "
"šimtai devyniasdešimt trys sikstilijonai šeši šimtai "
"šešiasdešimt trys kvintilijonai trisdešimt keturi kvadrilijonai "
"aštuoni šimtai dvidešimt du trilijonai aštuoni šimtai dvidešimt "
"keturi milijardai trys šimtai aštuoniasdešimt keturi milijonai "
"du šimtai dvidešimt tūkstančių du šimtai devyniasdešimt vienas")
# print(fill(n2w(1000000000000000000000000000000)))
# naintilijonas
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='lt', to='ordinal')
def test_to_currency(self):
self.assertEqual(
num2words(1.0, lang='lt', to='currency', currency='LTL'),
'vienas litas, nulis centų'
)
self.assertEqual(
num2words(1234.56, lang='lt', to='currency', currency='LTL'),
'vienas tūkstantis du šimtai trisdešimt keturi litai, '
'penkiasdešimt šeši centai'
)
self.assertEqual(
num2words(-1251985, lang='lt', to='currency', currency='EUR',
cents=False),
'minus dvylika tūkstančių penki šimtai devyniolika eurų, '
'85 centai'
)
self.assertEqual(
num2words(1.0, lang='lt', to='currency', currency='EUR'),
'vienas euras, nulis centų'
)
self.assertEqual(
num2words(1234.56, lang='lt', to='currency', currency='EUR'),
'vienas tūkstantis du šimtai trisdešimt keturi eurai, '
'penkiasdešimt šeši centai'
)

View File

@@ -8,6 +8,41 @@ from num2words import num2words
class Num2WordsLVTest(TestCase): class Num2WordsLVTest(TestCase):
def test_to_cardinal(self): def test_to_cardinal(self):
self.assertEqual(num2words(100, lang='lv'), 'simts')
self.assertEqual(num2words(101, lang='lv'), 'simtu viens')
self.assertEqual(num2words(110, lang='lv'), 'simts desmit')
self.assertEqual(num2words(115, lang='lv'), 'simts piecpadsmit')
self.assertEqual(num2words(123, lang='lv'), 'simts divdesmit trīs')
self.assertEqual(num2words(1000, lang='lv'), 'tūkstotis')
self.assertEqual(num2words(1001, lang='lv'), 'tūkstotis viens')
self.assertEqual(num2words(2012, lang='lv'),
'divi tūkstoši divpadsmit')
self.assertEqual(
num2words(1234567890, lang='lv'),
'miljards divi simti trīsdesmit četri miljoni pieci simti '
'sešdesmit septiņi tūkstoši astoņi simti deviņdesmit')
self.assertEqual(
num2words(215461407892039002157189883901676, lang='lv'),
'divi simti piecpadsmit nontiljoni četri simti sešdesmit '
'viens oktiljons četri simti septiņi septiljoni astoņi '
'simti deviņdesmit divi sikstiljoni trīsdesmit deviņi '
'kvintiljoni divi kvadriljoni simts piecdesmit septiņi '
'triljoni simts astoņdesmit deviņi miljardi astoņi simti '
'astoņdesmit trīs miljoni deviņi simti viens tūkstotis '
'seši simti septiņdesmit seši')
self.assertEqual(
num2words(719094234693663034822824384220291, lang='lv'),
'septiņi simti deviņpadsmit nontiljoni deviņdesmit četri '
'oktiljoni divi simti trīsdesmit četri septiljoni seši simti '
'deviņdesmit trīs sikstiljoni seši simti sešdesmit trīs '
'kvintiljoni trīsdesmit četri kvadriljoni astoņi simti '
'divdesmit divi triljoni astoņi simti divdesmit četri '
'miljardi trīs simti astoņdesmit četri miljoni divi simti '
'divdesmit tūkstoši divi simti deviņdesmit viens')
# >>> print(fill(n2w(1000000000000000000000000000000)))
# nontiljons
self.assertEqual(num2words(0, lang='lv'), 'nulle') self.assertEqual(num2words(0, lang='lv'), 'nulle')
self.assertEqual(num2words(5, lang='lv'), "pieci") self.assertEqual(num2words(5, lang='lv'), "pieci")
self.assertEqual(num2words(15, lang='lv'), "piecpadsmit") self.assertEqual(num2words(15, lang='lv'), "piecpadsmit")
@@ -25,7 +60,46 @@ class Num2WordsLVTest(TestCase):
"miljons simts trīsdesmit deviņi" "miljons simts trīsdesmit deviņi"
) )
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='lv', to='ordinal')
def test_to_currency(self): def test_to_currency(self):
self.assertEqual(
num2words(1.0, lang='lv', to='currency', currency='EUR'),
"viens eiro, nulle centu"
)
self.assertEqual(
num2words(1.0, lang='lv', to='currency', currency='LVL'),
"viens lats, nulle santīmu"
)
self.assertEqual(
num2words(1234.56, lang='lv', to='currency', currency='EUR'),
"tūkstotis divi simti trīsdesmit četri eiro, piecdesmit seši centi"
)
self.assertEqual(
num2words(1234.56, lang='lv', to='currency', currency='LVL'),
"tūkstotis divi simti trīsdesmit četri lati, "
"piecdesmit seši santīmi"
)
self.assertEqual(
num2words(10111, lang='lv', to='currency', seperator=' un',
currency='EUR'),
"simtu viens eiro un vienpadsmit centi"
)
self.assertEqual(
num2words(10121, lang='lv', to='currency', seperator=' un',
currency='LVL'),
"simtu viens lats un divdesmit viens santīms"
)
self.assertEqual(
num2words(-1251985, lang='lv', to='currency', cents=False,
currency='EUR'),
"mīnus divpadsmit tūkstoši pieci simti deviņpadsmit eiro,"
" 85 centi"
)
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='EUR'), cents=False, currency='EUR'),
@@ -41,13 +115,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', prefix=False), cents=False, currency='USD', adjective=False),
"trīsdesmit astoņi dolāri un 40 centi" "trīsdesmit astoņi dolāri un 40 centi"
) )
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', prefix=True), cents=False, currency='USD', adjective=True),
"trīsdesmit astoņi ASV dolāri un 40 centi" "trīsdesmit astoņi ASV dolāri un 40 centi"
) )

View File

@@ -19,7 +19,6 @@ from __future__ import unicode_literals
from unittest import TestCase from unittest import TestCase
from num2words import num2words from num2words import num2words
from num2words.lang_PL import to_currency
class Num2WordsPLTest(TestCase): class Num2WordsPLTest(TestCase):
@@ -66,36 +65,48 @@ class Num2WordsPLTest(TestCase):
"tysięcy dwieście dziewięćdzisiąt jeden" "tysięcy dwieście dziewięćdzisiąt jeden"
) )
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='pl', to='ordinal')
def test_currency(self): def test_currency(self):
self.assertEqual(to_currency(1.0, 'EUR'), "jeden euro, zero centów")
self.assertEqual(to_currency(1.0, 'PLN'), "jeden złoty, zero groszy")
self.assertEqual( self.assertEqual(
to_currency(1234.56, 'EUR'), num2words(1.0, lang='pl', to='currency', currency='EUR'),
"jeden euro, zero centów")
self.assertEqual(
num2words(1.0, lang='pl', to='currency', currency='PLN'),
"jeden złoty, zero groszy")
self.assertEqual(
num2words(1234.56, lang='pl', to='currency', currency='EUR'),
"tysiąc dwieście trzydzieści cztery euro, pięćdziesiąt sześć " "tysiąc dwieście trzydzieści cztery euro, pięćdziesiąt sześć "
"centów" "centów"
) )
self.assertEqual( self.assertEqual(
to_currency(1234.56, 'PLN'), num2words(1234.56, lang='pl', to='currency', currency='PLN'),
"tysiąc dwieście trzydzieści cztery złote, pięćdziesiąt sześć " "tysiąc dwieście trzydzieści cztery złote, pięćdziesiąt sześć "
"groszy" "groszy"
) )
self.assertEqual( self.assertEqual(
to_currency(10111, 'EUR', seperator=' i'), num2words(10111, lang='pl', to='currency', currency='EUR',
seperator=' i'),
"sto jeden euro i jedenaście centów" "sto jeden euro i jedenaście centów"
) )
self.assertEqual( self.assertEqual(
to_currency(10121, 'PLN', seperator=' i'), num2words(10121, lang='pl', to='currency', currency='PLN',
seperator=' i'),
"sto jeden złotych i dwadzieścia jeden groszy" "sto jeden złotych i dwadzieścia jeden groszy"
) )
self.assertEqual( self.assertEqual(
to_currency(-1251985, cents=False), num2words(-1251985, lang='pl', to='currency', cents=False),
"minus dwanaście tysięcy pięćset dziewiętnaście euro, 85 centów" "minus dwanaście tysięcy pięćset dziewiętnaście euro, 85 centów"
) )
self.assertEqual( self.assertEqual(
to_currency(123.50, 'PLN', seperator=' i'), num2words(123.50, lang='pl', to='currency', currency='PLN',
seperator=' i'),
"sto dwadzieścia trzy złote i pięćdziesiąt groszy" "sto dwadzieścia trzy złote i pięćdziesiąt groszy"
) )
self.assertEqual( self.assertEqual(
to_currency(1950, cents=False), num2words(1950, lang='pl', to='currency', cents=False),
"dziewiętnaście euro, 50 centów" "dziewiętnaście euro, 50 centów"
) )

View File

@@ -23,6 +23,37 @@ from num2words import num2words
class Num2WordsRUTest(TestCase): class Num2WordsRUTest(TestCase):
def test_cardinal(self): def test_cardinal(self):
self.assertEqual(num2words(100, lang='ru'), "сто")
self.assertEqual(num2words(101, lang='ru'), "сто один")
self.assertEqual(num2words(110, lang='ru'), "сто десять")
self.assertEqual(num2words(115, lang='ru'), "сто пятнадцать")
self.assertEqual(num2words(123, lang='ru'), "сто двадцать три")
self.assertEqual(num2words(1000, lang='ru'), "одна тысяча")
self.assertEqual(num2words(1001, lang='ru'), "одна тысяча один")
self.assertEqual(num2words(2012, lang='ru'), "две тысячи двенадцать")
self.assertEqual(
num2words(12519.85, lang='ru'),
"двенадцать тысяч пятьсот девятнадцать запятая восемьдесят пять")
self.assertEqual(
num2words(1234567890, lang='ru'),
"один миллиард двести тридцать четыре миллиона пятьсот "
"шестьдесят семь тысяч восемьсот девяносто")
self.assertEqual(
num2words(215461407892039002157189883901676, lang='ru'),
"двести пятнадцать нониллионов четыреста шестьдесят один "
"октиллион четыреста семь септиллионов восемьсот девяносто "
"два секстиллиона тридцать девять квинтиллионов два квадриллиона "
"сто пятьдесят семь триллионов сто восемьдесят девять миллиардов "
"восемьсот восемьдесят три миллиона девятьсот одна тысяча "
"шестьсот семьдесят шесть")
self.assertEqual(
num2words(719094234693663034822824384220291, lang='ru'),
"семьсот девятнадцать нониллионов девяносто четыре октиллиона "
"двести тридцать четыре септиллиона шестьсот девяносто три "
"секстиллиона шестьсот шестьдесят три квинтиллиона тридцать "
"четыре квадриллиона восемьсот двадцать два триллиона восемьсот "
"двадцать четыре миллиарда триста восемьдесят четыре миллиона "
"двести двадцать тысяч двести девяносто один")
self.assertEqual(num2words(5, lang='ru'), "пять") self.assertEqual(num2words(5, lang='ru'), "пять")
self.assertEqual(num2words(15, lang='ru'), "пятнадцать") self.assertEqual(num2words(15, lang='ru'), "пятнадцать")
self.assertEqual(num2words(154, lang='ru'), "сто пятьдесят четыре") self.assertEqual(num2words(154, lang='ru'), "сто пятьдесят четыре")
@@ -44,7 +75,53 @@ class Num2WordsRUTest(TestCase):
"пятьсот шестьдесят один запятая сорок два" "пятьсот шестьдесят один запятая сорок два"
) )
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='ru', to='ordinal')
def test_to_currency(self): def test_to_currency(self):
self.assertEqual(
num2words(1.0, lang='ru', to='currency', currency='EUR'),
'один евро, ноль центов'
)
self.assertEqual(
num2words(1.0, lang='ru', to='currency', currency='RUB'),
'один рубль, ноль копеек'
)
self.assertEqual(
num2words(1234.56, lang='ru', to='currency', currency='EUR'),
'одна тысяча двести тридцать четыре евро, пятьдесят шесть центов'
)
self.assertEqual(
num2words(1234.56, lang='ru', to='currency', currency='RUB'),
'одна тысяча двести тридцать четыре рубля, пятьдесят шесть копеек'
)
self.assertEqual(
num2words(10111, lang='ru', to='currency', currency='EUR',
seperator=' и'),
'сто один евро и одиннадцать центов'
)
self.assertEqual(
num2words(10121, lang='ru', to='currency', currency='RUB',
seperator=' и'),
'сто один рубль и двадцать одна копейка'
)
self.assertEqual(
num2words(10122, lang='ru', to='currency', currency='RUB',
seperator=' и'),
'сто один рубль и двадцать две копейки'
)
self.assertEqual(
num2words(10121, lang='ru', to='currency', currency='EUR',
seperator=' и'),
'сто один евро и двадцать один цент'
)
self.assertEqual(
num2words(-1251985, lang='ru', to='currency', currency='EUR',
cents=False),
'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов'
)
self.assertEqual( self.assertEqual(
num2words('38.4', lang='ru', to='currency', seperator=' и', num2words('38.4', lang='ru', to='currency', seperator=' и',
cents=False, currency='EUR'), cents=False, currency='EUR'),

View File

@@ -21,6 +21,41 @@ from num2words import num2words
class Num2WordsUKTest(TestCase): 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ссот дев'яносто")
# 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сть")
# self.assertEqual(
# num2words(719094234693663034822824384220291, lang='uk'),
# "ссот дев'ятнадцять нонiльйонiв дев'яносто чотири октильйони "
# "двiстi тридцять чотири септильйони шiстсот дев'яносто три "
# "секстильйони шiстсот шiстдесят три квiнтильйони тридцять "
# "чотири квадрильйони вiссот двадцять два трильйони вiссот "
# "двадцять чотири мiльярди триста вiсiмдесят чотири мiльйона "
# "двiстi двадцять тисяч двiстi дев'яносто один")
def test_and_join_199(self): def test_and_join_199(self):
self.assertEqual(num2words(187, lang='uk'), "сто вiсiмдесят с") self.assertEqual(num2words(187, lang='uk'), "сто вiсiмдесят с")
@@ -38,7 +73,59 @@ class Num2WordsUKTest(TestCase):
num2words(12.31, lang='uk'), "дванадцять кома тридцять одна" num2words(12.31, lang='uk'), "дванадцять кома тридцять одна"
) )
def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='uk', to='ordinal')
def test_to_currency(self): 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',
# seperator=u' та'),
# "сто один евро та одинадцять центiв"
# )
self.assertEqual(
num2words(10121, lang='uk', to='currency', currency='UAH',
seperator=u' та'),
"сто одна гривня та двадцять одна копiйка"
)
self.assertEqual(
num2words(10121, lang='uk', to='currency', currency='UAH',
seperator=u' та'),
"сто одна гривня та двадцять одна копiйка"
)
self.assertEqual(
num2words(10122, lang='uk', to='currency', currency='UAH',
seperator=u' та'),
"сто одна гривня та двадцять двi копiйки"
)
# self.assertEqual(
# num2words(10121, lang='uk', to='currency', currency='EUR',
# seperator=u' та'),
# "сто один евро та двадцять один цент"
# )
self.assertEqual(
num2words(-1251985, lang='uk', to='currency', currency='EUR',
cents=False),
"мiнус дванадцять тисяч п'ятсот дев'ятнадцять евро, 85 центiв"
)
self.assertEqual( self.assertEqual(
num2words('38.4', lang='uk', to='currency', seperator=' и', num2words('38.4', lang='uk', to='currency', seperator=' и',
cents=False, currency='EUR'), cents=False, currency='EUR'),