mirror of
https://github.com/bblaz/num2words.git
synced 2025-12-06 06:42:25 +00:00
@@ -70,6 +70,7 @@ cardinal one.
|
||||
* ``ru`` (Russian)
|
||||
* ``tr`` (Turkish)
|
||||
* ``vn`` (Vietnamese)
|
||||
* ``uk`` (Ukrainian)
|
||||
|
||||
You can supply values like ``fr_FR``, the code will be correctly interpreted. If
|
||||
you supply an unsupported language, ``NotImplementedError`` is raised.
|
||||
|
||||
@@ -39,6 +39,7 @@ from . import lang_ES_VE
|
||||
from . import lang_ES_CO
|
||||
from . import lang_VN
|
||||
from . import lang_TR
|
||||
from . import lang_UK
|
||||
|
||||
|
||||
CONVERTER_CLASSES = {
|
||||
@@ -64,7 +65,8 @@ CONVERTER_CLASSES = {
|
||||
'he': lang_HE.Num2Word_HE(),
|
||||
'it': lang_IT.Num2Word_IT(),
|
||||
'vi_VN': lang_VN.Num2Word_VN(),
|
||||
'tr': lang_TR.Num2Word_TR()
|
||||
'tr': lang_TR.Num2Word_TR(),
|
||||
'uk': lang_UK.Num2Word_UK()
|
||||
}
|
||||
|
||||
def num2words(number, ordinal=False, lang='en'):
|
||||
|
||||
316
num2words/lang_UK.py
Normal file
316
num2words/lang_UK.py
Normal file
@@ -0,0 +1,316 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
|
||||
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA
|
||||
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)]))
|
||||
нуль один два три чотири п'ять ш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с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мдесят три
|
||||
м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ст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
|
||||
|
||||
ZERO = (u'нуль',)
|
||||
|
||||
ONES_FEMININE = {
|
||||
1: (u'одна',),
|
||||
2: (u'двi',),
|
||||
3: (u'три',),
|
||||
4: (u'чотири',),
|
||||
5: (u'п\'ять',),
|
||||
6: (u'шiсть',),
|
||||
7: (u'сiм',),
|
||||
8: (u'вiсiм',),
|
||||
9: (u'дев\'ять',),
|
||||
}
|
||||
|
||||
ONES = {
|
||||
1: (u'один',),
|
||||
2: (u'два',),
|
||||
3: (u'три',),
|
||||
4: (u'чотири',),
|
||||
5: (u'п\'ять',),
|
||||
6: (u'шiсть',),
|
||||
7: (u'сiм',),
|
||||
8: (u'вiсiм',),
|
||||
9: (u'дев\'ять',),
|
||||
}
|
||||
|
||||
TENS = {
|
||||
0: (u'десять',),
|
||||
1: (u'одинадцять',),
|
||||
2: (u'дванадцять',),
|
||||
3: (u'тринадцять',),
|
||||
4: (u'чотирнадцять',),
|
||||
5: (u'п\'ятнадцять',),
|
||||
6: (u'шiстнадцять',),
|
||||
7: (u'сiмнадцять',),
|
||||
8: (u'вiсiмнадцять',),
|
||||
9: (u'дев\'ятнадцять',),
|
||||
}
|
||||
|
||||
TWENTIES = {
|
||||
2: (u'двадцять',),
|
||||
3: (u'тридцять',),
|
||||
4: (u'сорок',),
|
||||
5: (u'п\'ятдесят',),
|
||||
6: (u'шiстдесят',),
|
||||
7: (u'сiмдесят',),
|
||||
8: (u'вiсiмдесят',),
|
||||
9: (u'дев\'яносто',),
|
||||
}
|
||||
|
||||
HUNDREDS = {
|
||||
1: (u'сто',),
|
||||
2: (u'двiстi',),
|
||||
3: (u'триста',),
|
||||
4: (u'чотириста',),
|
||||
5: (u'п\'ятсот',),
|
||||
6: (u'шiстсот',),
|
||||
7: (u'сiмсот',),
|
||||
8: (u'вiсiмсот',),
|
||||
9: (u'дев\'ятсот',),
|
||||
}
|
||||
|
||||
THOUSANDS = {
|
||||
1: (u'тисяча', u'тисячi', u'тисяч'), # 10^3
|
||||
2: (u'мiльйон', u'мiльйони', u'мiльйонiв'), # 10^6
|
||||
3: (u'мiльярд', u'мiльярди', u'мiльярдiв'), # 10^9
|
||||
4: (u'трильйон', u'трильйони', u'трильйонiв'), # 10^12
|
||||
5: (u'квадрильйон', u'квадрильйони', u'квадрильйонiв'), # 10^15
|
||||
6: (u'квiнтильйон', u'квiнтильйони', u'квiнтильйонiв'), # 10^18
|
||||
7: (u'секстильйон', u'секстильйони', u'секстильйонiв'), # 10^21
|
||||
8: (u'септильйон', u'септильйони', u'септильйонiв'), # 10^24
|
||||
9: (u'октильйон', u'октильйони', u'октильйонiв'), #10^27
|
||||
10: (u'нонiльйон', u'нонiльйони', u'нонiльйонiв'), # 10^30
|
||||
}
|
||||
|
||||
CURRENCIES = {
|
||||
'UAH': (
|
||||
(u'гривня', u'гривнi', u'гривень'), (u'копiйка', u'копiйки', u'копiйок')
|
||||
),
|
||||
'EUR': (
|
||||
(u'евро', u'евро', u'евро'), (u'цент', u'центи', u'центiв')
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
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):
|
||||
#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 % 10 == 1:
|
||||
form = 0
|
||||
elif (n % 10 > 1 and n % 10 < 5):
|
||||
form = 1
|
||||
else:
|
||||
form = 2
|
||||
else:
|
||||
form = 2
|
||||
|
||||
return forms[form]
|
||||
|
||||
|
||||
def int2word(n, feminine=True):
|
||||
if n < 0:
|
||||
return ' '.join([u'мiнус', int2word(abs(n))])
|
||||
|
||||
if n == 0:
|
||||
return ZERO[0]
|
||||
|
||||
words = []
|
||||
chunks = list(splitby3(str(n)))
|
||||
i = len(chunks)
|
||||
for x in chunks:
|
||||
i -= 1
|
||||
n1, n2, n3 = get_digits(x)
|
||||
|
||||
if n3 > 0:
|
||||
words.append(HUNDREDS[n3][0])
|
||||
|
||||
if n2 > 1:
|
||||
words.append(TWENTIES[n2][0])
|
||||
|
||||
if n2 == 1:
|
||||
words.append(TENS[n1][0])
|
||||
#elif n1 > 0 and not (i > 0 and x == 1):
|
||||
elif n1 > 0:
|
||||
ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES
|
||||
words.append(ones[n1][0])
|
||||
|
||||
|
||||
if i > 0 and ((n1+n2+n3) > 0):
|
||||
words.append(pluralize(x, THOUSANDS[i]))
|
||||
|
||||
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=','):
|
||||
if type(n) == int:
|
||||
if n < 0:
|
||||
minus = True
|
||||
else:
|
||||
minus = False
|
||||
|
||||
n = abs(n)
|
||||
left = n / 100
|
||||
right = n % 100
|
||||
else:
|
||||
n = str(n).replace(',', '.')
|
||||
if '.' in n:
|
||||
left, right = n.split('.')
|
||||
else:
|
||||
left, right = n, 0
|
||||
left, right = int(left), int(right)
|
||||
minus = False
|
||||
cr1, cr2 = CURRENCIES[currency]
|
||||
|
||||
if minus:
|
||||
minus_str = "мiнус "
|
||||
else:
|
||||
minus_str = ""
|
||||
|
||||
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):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
29
tests/test_uk.py
Normal file
29
tests/test_uk.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# 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 unittest import TestCase
|
||||
|
||||
from num2words import num2words
|
||||
|
||||
class Num2WordsUKTest(TestCase):
|
||||
def test_and_join_199(self):
|
||||
self.assertEqual(num2words(187,lang='uk'), u"сто вiсiмдесят сiм")
|
||||
|
||||
def test_cardinal_for_float_number(self):
|
||||
self.assertEqual(num2words(12.40,lang='uk'), u"дванадцять кома чотири")
|
||||
self.assertEqual(num2words(17.31,lang='uk'), u"сiмнадцять кома тридцять одна")
|
||||
self.assertEqual(num2words(14.13,lang='uk'), u"чотирнадцять кома тринадцять")
|
||||
self.assertEqual(num2words(12.31,lang='uk'), u"дванадцять кома тридцять одна")
|
||||
Reference in New Issue
Block a user