add Thai Language from Thailand (#139)

* add Thai

* change splitby3 to splitbyx

* change lang_th to use function from currency

* make Num2Word_TH inherit from Num2Word_Base

* comment out test failed in 2.7 env

* fix python2.7 error

* add USD EUR for Thai

* pep8 fix

* added Thai
This commit is contained in:
pipech
2017-12-14 23:48:12 +07:00
committed by Ernesto Rodriguez Ortiz
parent efce631944
commit ab54bed93a
14 changed files with 1442 additions and 1025 deletions

View File

@@ -41,6 +41,7 @@ from . import lang_TR
from . import lang_NL
from . import lang_UK
from . import lang_SL
from . import lang_TH
CONVERTER_CLASSES = {
'ar': lang_AR.Num2Word_AR(),
@@ -65,6 +66,7 @@ CONVERTER_CLASSES = {
'he': lang_HE.Num2Word_HE(),
'it': lang_IT.Num2Word_IT(),
'vi_VN': lang_VN.Num2Word_VN(),
'th': lang_TH.Num2Word_TH(),
'tr': lang_TR.Num2Word_TR(),
'nl': lang_NL.Num2Word_NL(),
'uk': lang_UK.Num2Word_UK()

View File

@@ -1,39 +1,31 @@
from __future__ import division
from decimal import Decimal
from decimal import ROUND_HALF_UP, Decimal
def parse_currency_parts(value):
def parse_currency_parts(value, is_int_with_cents=True):
if isinstance(value, int):
# assume cents if value is integer
negative = value < 0
value = abs(value)
integer, cents = divmod(value, 100)
if is_int_with_cents:
# assume cents if value is integer
negative = value < 0
value = abs(value)
integer, cents = divmod(value, 100)
else:
negative = value < 0
integer, cents = abs(value), 0
elif isinstance(value, Decimal):
else:
value = Decimal(value)
value = value.quantize(
Decimal('.01'),
rounding=ROUND_HALF_UP
)
negative = value < 0
value = abs(value)
integer, fraction = divmod(value, 1)
integer = int(integer)
cents = int(fraction * 100)
else:
# @TODO consider using something (babel) that does locale aware parsing
value = str(value).replace(',', '.')
negative = value.startswith('-')
if negative:
value = value.lstrip('-')
if '.' in value:
integer, fraction = value.rsplit('.', 1)
fraction = fraction.ljust(2, "0")
else:
integer, fraction = value, 0
integer = int(integer)
cents = int(fraction)
return integer, cents, negative

View File

@@ -1,148 +1,148 @@
# -*- 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
from __future__ import print_function, unicode_literals
from .utils import get_digits, splitby3
ZERO = (u'אפס',)
ONES = {
1: (u'אחד',),
2: (u'שנים',),
3: (u'שלש',),
4: (u'ארבע',),
5: (u'חמש',),
6: (u'שש',),
7: (u'שבע',),
8: (u'שמנה',),
9: (u'תשע',),
}
TENS = {
0: (u'עשר',),
1: (u'אחד עשרה',),
2: (u'שנים עשרה',),
3: (u'שלש עשרה',),
4: (u'ארבע עשרה',),
5: (u'חמש עשרה',),
6: (u'שש עשרה',),
7: (u'שבע עשרה',),
8: (u'שמנה עשרה',),
9: (u'תשע עשרה',),
}
TWENTIES = {
2: (u'עשרים',),
3: (u'שלשים',),
4: (u'ארבעים',),
5: (u'חמישים',),
6: (u'ששים',),
7: (u'שבעים',),
8: (u'שמנים',),
9: (u'תשעים',),
}
HUNDRED = {
1: (u'מאה',),
2: (u'מאתיים',),
3: (u'מאות',)
}
THOUSANDS = {
1: (u'אלף',),
2: (u'אלפיים',),
}
AND = u'ו'
def pluralize(n, forms):
# gettext implementation:
# (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
return forms[form]
def int2word(n):
if n > 9999: # doesn't yet work for numbers this big
raise NotImplementedError()
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)
# print str(n3) + str(n2) + str(n1)
if n3 > 0:
if n3 <= 2:
words.append(HUNDRED[n3][0])
else:
words.append(ONES[n3][0])
words.append(HUNDRED[3][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):
words.append(ONES[n1][0])
if i > 0:
if i <= 2:
words.append(THOUSANDS[i][0])
else:
words.append(ONES[i][0])
words.append(THOUSANDS[1][0])
if len(words) > 1:
words[-1] = AND + words[-1]
return ' '.join(words)
def n2w(n):
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, seperator=','):
raise NotImplementedError()
class Num2Word_HE(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
if __name__ == '__main__':
yo = Num2Word_HE()
nums = [1, 11, 21, 24, 99, 100, 101, 200, 211, 345, 1000, 1011]
for num in nums:
print(num, yo.to_cardinal(num))
# -*- 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
from __future__ import print_function, unicode_literals
from .utils import get_digits, splitbyx
ZERO = (u'אפס',)
ONES = {
1: (u'אחד',),
2: (u'שנים',),
3: (u'שלש',),
4: (u'ארבע',),
5: (u'חמש',),
6: (u'שש',),
7: (u'שבע',),
8: (u'שמנה',),
9: (u'תשע',),
}
TENS = {
0: (u'עשר',),
1: (u'אחד עשרה',),
2: (u'שנים עשרה',),
3: (u'שלש עשרה',),
4: (u'ארבע עשרה',),
5: (u'חמש עשרה',),
6: (u'שש עשרה',),
7: (u'שבע עשרה',),
8: (u'שמנה עשרה',),
9: (u'תשע עשרה',),
}
TWENTIES = {
2: (u'עשרים',),
3: (u'שלשים',),
4: (u'ארבעים',),
5: (u'חמישים',),
6: (u'ששים',),
7: (u'שבעים',),
8: (u'שמנים',),
9: (u'תשעים',),
}
HUNDRED = {
1: (u'מאה',),
2: (u'מאתיים',),
3: (u'מאות',)
}
THOUSANDS = {
1: (u'אלף',),
2: (u'אלפיים',),
}
AND = u'ו'
def pluralize(n, forms):
# gettext implementation:
# (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
return forms[form]
def int2word(n):
if n > 9999: # doesn't yet work for numbers this big
raise NotImplementedError()
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
i = len(chunks)
for x in chunks:
i -= 1
n1, n2, n3 = get_digits(x)
# print str(n3) + str(n2) + str(n1)
if n3 > 0:
if n3 <= 2:
words.append(HUNDRED[n3][0])
else:
words.append(ONES[n3][0])
words.append(HUNDRED[3][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):
words.append(ONES[n1][0])
if i > 0:
if i <= 2:
words.append(THOUSANDS[i][0])
else:
words.append(ONES[i][0])
words.append(THOUSANDS[1][0])
if len(words) > 1:
words[-1] = AND + words[-1]
return ' '.join(words)
def n2w(n):
return int2word(int(n))
def to_currency(n, currency='EUR', cents=True, seperator=','):
raise NotImplementedError()
class Num2Word_HE(object):
def to_cardinal(self, number):
return n2w(number)
def to_ordinal(self, number):
raise NotImplementedError()
if __name__ == '__main__':
yo = Num2Word_HE()
nums = [1, 11, 21, 24, 99, 100, 101, 200, 211, 345, 1000, 1011]
for num in nums:
print(num, yo.to_cardinal(num))

View File

@@ -1,144 +1,144 @@
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('nulis',)
ONES = {
1: ('vienas',),
2: ('du',),
3: ('trys',),
4: ('keturi',),
5: ('penki',),
6: ('šeši',),
7: ('septyni',),
8: ('aštuoni',),
9: ('devyni',),
}
TENS = {
0: ('dešimt',),
1: ('vienuolika',),
2: ('dvylika',),
3: ('trylika',),
4: ('keturiolika',),
5: ('penkiolika',),
6: ('šešiolika',),
7: ('septyniolika',),
8: ('aštuoniolika',),
9: ('devyniolika',),
}
TWENTIES = {
2: ('dvidešimt',),
3: ('trisdešimt',),
4: ('keturiasdešimt',),
5: ('penkiasdešimt',),
6: ('šešiasdešimt',),
7: ('septyniasdešimt',),
8: ('aštuoniasdešimt',),
9: ('devyniasdešimt',),
}
HUNDRED = ('šimtas', 'šimtai')
THOUSANDS = {
1: ('tūkstantis', 'tūkstančiai', 'tūkstančių'),
2: ('milijonas', 'milijonai', 'milijonų'),
3: ('milijardas', 'milijardai', 'milijardų'),
4: ('trilijonas', 'trilijonai', 'trilijonų'),
5: ('kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'),
6: ('kvintilijonas', 'kvintilijonai', 'kvintilijonų'),
7: ('sikstilijonas', 'sikstilijonai', 'sikstilijonų'),
8: ('septilijonas', 'septilijonai', 'septilijonų'),
9: ('oktilijonas', 'oktilijonai', 'oktilijonų'),
10: ('naintilijonas', 'naintilijonai', 'naintilijonų'),
}
class Num2Word_LT(Num2Word_Base):
CURRENCY_FORMS = {
'LTL': (('litas', 'litai', 'litų'), ('centas', 'centai', 'centų')),
'EUR': (('euras', 'eurai', 'eurų'), ('centas', 'centai', 'centų')),
}
def setup(self):
self.negword = "minus"
self.pointword = "kablelis"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def pluralize(self, n, forms):
n1, n2, n3 = get_digits(n)
if n2 == 1 or n1 == 0 or n == 0:
return forms[2]
elif n1 == 1:
return forms[0]
else:
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 to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, 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(ONES[n3][0])
if n3 > 1:
words.append(HUNDRED[1])
else:
words.append(HUNDRED[0])
if n2 > 1:
words.append(TWENTIES[n2][0])
if n2 == 1:
words.append(TENS[n1][0])
elif n1 > 0:
words.append(ONES[n1][0])
if i > 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitbyx
ZERO = ('nulis',)
ONES = {
1: ('vienas',),
2: ('du',),
3: ('trys',),
4: ('keturi',),
5: ('penki',),
6: ('šeši',),
7: ('septyni',),
8: ('aštuoni',),
9: ('devyni',),
}
TENS = {
0: ('dešimt',),
1: ('vienuolika',),
2: ('dvylika',),
3: ('trylika',),
4: ('keturiolika',),
5: ('penkiolika',),
6: ('šešiolika',),
7: ('septyniolika',),
8: ('aštuoniolika',),
9: ('devyniolika',),
}
TWENTIES = {
2: ('dvidešimt',),
3: ('trisdešimt',),
4: ('keturiasdešimt',),
5: ('penkiasdešimt',),
6: ('šešiasdešimt',),
7: ('septyniasdešimt',),
8: ('aštuoniasdešimt',),
9: ('devyniasdešimt',),
}
HUNDRED = ('šimtas', 'šimtai')
THOUSANDS = {
1: ('tūkstantis', 'tūkstančiai', 'tūkstančių'),
2: ('milijonas', 'milijonai', 'milijonų'),
3: ('milijardas', 'milijardai', 'milijardų'),
4: ('trilijonas', 'trilijonai', 'trilijonų'),
5: ('kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'),
6: ('kvintilijonas', 'kvintilijonai', 'kvintilijonų'),
7: ('sikstilijonas', 'sikstilijonai', 'sikstilijonų'),
8: ('septilijonas', 'septilijonai', 'septilijonų'),
9: ('oktilijonas', 'oktilijonai', 'oktilijonų'),
10: ('naintilijonas', 'naintilijonai', 'naintilijonų'),
}
class Num2Word_LT(Num2Word_Base):
CURRENCY_FORMS = {
'LTL': (('litas', 'litai', 'litų'), ('centas', 'centai', 'centų')),
'EUR': (('euras', 'eurai', 'eurų'), ('centas', 'centai', 'centų')),
}
def setup(self):
self.negword = "minus"
self.pointword = "kablelis"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def pluralize(self, n, forms):
n1, n2, n3 = get_digits(n)
if n2 == 1 or n1 == 0 or n == 0:
return forms[2]
elif n1 == 1:
return forms[0]
else:
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 to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, n):
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
i = len(chunks)
for x in chunks:
i -= 1
n1, n2, n3 = get_digits(x)
if n3 > 0:
words.append(ONES[n3][0])
if n3 > 1:
words.append(HUNDRED[1])
else:
words.append(HUNDRED[0])
if n2 > 1:
words.append(TWENTIES[n2][0])
if n2 == 1:
words.append(TENS[n1][0])
elif n1 > 0:
words.append(ONES[n1][0])
if i > 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)

View File

@@ -1,183 +1,183 @@
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('nulle',)
ONES = {
1: ('viens',),
2: ('divi',),
3: ('trīs',),
4: ('četri',),
5: ('pieci',),
6: ('seši',),
7: ('septiņi',),
8: ('astoņi',),
9: ('deviņi',),
}
TENS = {
0: ('desmit',),
1: ('vienpadsmit',),
2: ('divpadsmit',),
3: ('trīspadsmit',),
4: ('četrpadsmit',),
5: ('piecpadsmit',),
6: ('sešpadsmit',),
7: ('septiņpadsmit',),
8: ('astoņpadsmit',),
9: ('deviņpadsmit',),
}
TWENTIES = {
2: ('divdesmit',),
3: ('trīsdesmit',),
4: ('četrdesmit',),
5: ('piecdesmit',),
6: ('sešdesmit',),
7: ('septiņdesmit',),
8: ('astoņdesmit',),
9: ('deviņdesmit',),
}
HUNDRED = ('simts', 'simti', 'simtu')
THOUSANDS = {
1: ('tūkstotis', 'tūkstoši', 'tūkstošu'),
2: ('miljons', 'miljoni', 'miljonu'),
3: ('miljards', 'miljardi', 'miljardu'),
4: ('triljons', 'triljoni', 'triljonu'),
5: ('kvadriljons', 'kvadriljoni', 'kvadriljonu'),
6: ('kvintiljons', 'kvintiljoni', 'kvintiljonu'),
7: ('sikstiljons', 'sikstiljoni', 'sikstiljonu'),
8: ('septiljons', 'septiljoni', 'septiljonu'),
9: ('oktiljons', 'oktiljoni', 'oktiljonu'),
10: ('nontiljons', 'nontiljoni', 'nontiljonu'),
}
GENERIC_DOLLARS = ('dolārs', 'dolāri', 'dolāru')
GENERIC_CENTS = ('cents', 'centi', 'centu')
GENERIC_KRONA = ('krona', 'kronas', 'kronu')
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
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
"""
CURRENCY_FORMS = {
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
# repalced by EUR
'EEK': (GENERIC_KRONA, GENERIC_CENTS),
'EUR': (('eiro', 'eiro', 'eiro'), GENERIC_CENTS),
'EUR_LEGAL': (('euro', 'euro', 'euro'), GENERIC_CENTS),
'GBP': (
('sterliņu mārciņa', 'sterliņu mārciņas', 'sterliņu mārciņu'),
('penss', 'pensi', 'pensu')),
# replaced by EUR
'LTL': (('lits', 'liti', 'litu'), GENERIC_CENTS),
# replaced by EUR
'LVL': (('lats', 'lati', 'latu'),
('santīms', 'santīmi', 'santīmu')),
'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
'RUB': (('rublis', 'rubļi', 'rubļu'),
('kapeika', 'kapeikas', 'kapeiku')),
'SEK': (GENERIC_KRONA, GENERIC_ERA),
'NOK': (GENERIC_KRONA, GENERIC_ERA),
'PLN': (('zlots', 'zloti', 'zlotu'),
('grasis', 'graši', 'grašu')),
}
CURRENCY_ADJECTIVES = {
'AUD': 'Austrālijas',
'CAD': 'Kanādas',
'EEK': 'Igaunijas',
'USD': 'ASV',
'RUB': 'Kreivijas',
'SEK': 'Zviedrijas',
'NOK': 'Norvēģijas',
}
def setup(self):
self.negword = "mīnus"
self.pointword = "komats"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, 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:
if n3 == 1 and n2 == 0 and n1 > 0:
words.append(HUNDRED[2])
elif n3 > 1:
words.append(ONES[n3][0])
words.append(HUNDRED[1])
else:
words.append(HUNDRED[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):
words.append(ONES[n1][0])
if i > 0 and x != 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitbyx
ZERO = ('nulle',)
ONES = {
1: ('viens',),
2: ('divi',),
3: ('trīs',),
4: ('četri',),
5: ('pieci',),
6: ('seši',),
7: ('septiņi',),
8: ('astoņi',),
9: ('deviņi',),
}
TENS = {
0: ('desmit',),
1: ('vienpadsmit',),
2: ('divpadsmit',),
3: ('trīspadsmit',),
4: ('četrpadsmit',),
5: ('piecpadsmit',),
6: ('sešpadsmit',),
7: ('septiņpadsmit',),
8: ('astoņpadsmit',),
9: ('deviņpadsmit',),
}
TWENTIES = {
2: ('divdesmit',),
3: ('trīsdesmit',),
4: ('četrdesmit',),
5: ('piecdesmit',),
6: ('sešdesmit',),
7: ('septiņdesmit',),
8: ('astoņdesmit',),
9: ('deviņdesmit',),
}
HUNDRED = ('simts', 'simti', 'simtu')
THOUSANDS = {
1: ('tūkstotis', 'tūkstoši', 'tūkstošu'),
2: ('miljons', 'miljoni', 'miljonu'),
3: ('miljards', 'miljardi', 'miljardu'),
4: ('triljons', 'triljoni', 'triljonu'),
5: ('kvadriljons', 'kvadriljoni', 'kvadriljonu'),
6: ('kvintiljons', 'kvintiljoni', 'kvintiljonu'),
7: ('sikstiljons', 'sikstiljoni', 'sikstiljonu'),
8: ('septiljons', 'septiljoni', 'septiljonu'),
9: ('oktiljons', 'oktiljoni', 'oktiljonu'),
10: ('nontiljons', 'nontiljoni', 'nontiljonu'),
}
GENERIC_DOLLARS = ('dolārs', 'dolāri', 'dolāru')
GENERIC_CENTS = ('cents', 'centi', 'centu')
GENERIC_KRONA = ('krona', 'kronas', 'kronu')
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
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
"""
CURRENCY_FORMS = {
'AUD': (GENERIC_DOLLARS, GENERIC_CENTS),
'CAD': (GENERIC_DOLLARS, GENERIC_CENTS),
# repalced by EUR
'EEK': (GENERIC_KRONA, GENERIC_CENTS),
'EUR': (('eiro', 'eiro', 'eiro'), GENERIC_CENTS),
'EUR_LEGAL': (('euro', 'euro', 'euro'), GENERIC_CENTS),
'GBP': (
('sterliņu mārciņa', 'sterliņu mārciņas', 'sterliņu mārciņu'),
('penss', 'pensi', 'pensu')),
# replaced by EUR
'LTL': (('lits', 'liti', 'litu'), GENERIC_CENTS),
# replaced by EUR
'LVL': (('lats', 'lati', 'latu'),
('santīms', 'santīmi', 'santīmu')),
'USD': (GENERIC_DOLLARS, GENERIC_CENTS),
'RUB': (('rublis', 'rubļi', 'rubļu'),
('kapeika', 'kapeikas', 'kapeiku')),
'SEK': (GENERIC_KRONA, GENERIC_ERA),
'NOK': (GENERIC_KRONA, GENERIC_ERA),
'PLN': (('zlots', 'zloti', 'zlotu'),
('grasis', 'graši', 'grašu')),
}
CURRENCY_ADJECTIVES = {
'AUD': 'Austrālijas',
'CAD': 'Kanādas',
'EEK': 'Igaunijas',
'USD': 'ASV',
'RUB': 'Kreivijas',
'SEK': 'Zviedrijas',
'NOK': 'Norvēģijas',
}
def setup(self):
self.negword = "mīnus"
self.pointword = "komats"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, n):
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
i = len(chunks)
for x in chunks:
i -= 1
n1, n2, n3 = get_digits(x)
if n3 > 0:
if n3 == 1 and n2 == 0 and n1 > 0:
words.append(HUNDRED[2])
elif n3 > 1:
words.append(ONES[n3][0])
words.append(HUNDRED[1])
else:
words.append(HUNDRED[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):
words.append(ONES[n1][0])
if i > 0 and x != 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)

View File

@@ -1,153 +1,153 @@
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('zero',)
ONES = {
1: ('jeden',),
2: ('dwa',),
3: ('trzy',),
4: ('cztery',),
5: ('pięć',),
6: ('sześć',),
7: ('siedem',),
8: ('osiem',),
9: ('dziewięć',),
}
TENS = {
0: ('dziesięć',),
1: ('jedenaście',),
2: ('dwanaście',),
3: ('trzynaście',),
4: ('czternaście',),
5: ('piętnaście',),
6: ('szesnaście',),
7: ('siedemnaście',),
8: ('osiemnaście',),
9: ('dziewiętnaście',),
}
TWENTIES = {
2: ('dwadzieścia',),
3: ('trzydzieści',),
4: ('czterdzieści',),
5: ('pięćdziesiąt',),
6: ('sześćdziesiąt',),
7: ('siedemdziesiąt',),
8: ('osiemdziesiąt',),
9: ('dziewięćdzisiąt',),
}
HUNDREDS = {
1: ('sto',),
2: ('dwieście',),
3: ('trzysta',),
4: ('czterysta',),
5: ('pięćset',),
6: ('sześćset',),
7: ('siedemset',),
8: ('osiemset',),
9: ('dziewęćset',),
}
THOUSANDS = {
1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3
2: ('milion', 'miliony', 'milionów'), # 10^6
3: ('miliard', 'miliardy', 'miliardów'), # 10^9
4: ('bilion', 'biliony', 'bilionów'), # 10^12
5: ('biliard', 'biliardy', 'biliardów'), # 10^15
6: ('trylion', 'tryliony', 'trylionów'), # 10^18
7: ('tryliard', 'tryliardy', 'tryliardów'), # 10^21
8: ('kwadrylion', 'kwadryliony', 'kwadrylionów'), # 10^24
9: ('kwaryliard', 'kwadryliardy', 'kwadryliardów'), # 10^27
10: ('kwintylion', 'kwintyliony', 'kwintylionów'), # 10^30
}
class Num2Word_PL(Num2Word_Base):
CURRENCY_FORMS = {
'PLN': (
('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy')
),
'EUR': (
('euro', 'euro', 'euro'), ('cent', 'centy', 'centów')
),
}
def setup(self):
self.negword = "minus"
self.pointword = "przecinek"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
if n == 1:
form = 0
elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20):
form = 1
else:
form = 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, 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):
words.append(ONES[n1][0])
if i > 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitbyx
ZERO = ('zero',)
ONES = {
1: ('jeden',),
2: ('dwa',),
3: ('trzy',),
4: ('cztery',),
5: ('pięć',),
6: ('sześć',),
7: ('siedem',),
8: ('osiem',),
9: ('dziewięć',),
}
TENS = {
0: ('dziesięć',),
1: ('jedenaście',),
2: ('dwanaście',),
3: ('trzynaście',),
4: ('czternaście',),
5: ('piętnaście',),
6: ('szesnaście',),
7: ('siedemnaście',),
8: ('osiemnaście',),
9: ('dziewiętnaście',),
}
TWENTIES = {
2: ('dwadzieścia',),
3: ('trzydzieści',),
4: ('czterdzieści',),
5: ('pięćdziesiąt',),
6: ('sześćdziesiąt',),
7: ('siedemdziesiąt',),
8: ('osiemdziesiąt',),
9: ('dziewięćdzisiąt',),
}
HUNDREDS = {
1: ('sto',),
2: ('dwieście',),
3: ('trzysta',),
4: ('czterysta',),
5: ('pięćset',),
6: ('sześćset',),
7: ('siedemset',),
8: ('osiemset',),
9: ('dziewęćset',),
}
THOUSANDS = {
1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3
2: ('milion', 'miliony', 'milionów'), # 10^6
3: ('miliard', 'miliardy', 'miliardów'), # 10^9
4: ('bilion', 'biliony', 'bilionów'), # 10^12
5: ('biliard', 'biliardy', 'biliardów'), # 10^15
6: ('trylion', 'tryliony', 'trylionów'), # 10^18
7: ('tryliard', 'tryliardy', 'tryliardów'), # 10^21
8: ('kwadrylion', 'kwadryliony', 'kwadrylionów'), # 10^24
9: ('kwaryliard', 'kwadryliardy', 'kwadryliardów'), # 10^27
10: ('kwintylion', 'kwintyliony', 'kwintylionów'), # 10^30
}
class Num2Word_PL(Num2Word_Base):
CURRENCY_FORMS = {
'PLN': (
('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy')
),
'EUR': (
('euro', 'euro', 'euro'), ('cent', 'centy', 'centów')
),
}
def setup(self):
self.negword = "minus"
self.pointword = "przecinek"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
if n == 1:
form = 0
elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20):
form = 1
else:
form = 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _int2word(self, n):
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
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):
words.append(ONES[n1][0])
if i > 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)

View File

@@ -1,175 +1,175 @@
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('ноль',)
ONES_FEMININE = {
1: ('одна',),
2: ('две',),
3: ('три',),
4: ('четыре',),
5: ('пять',),
6: ('шесть',),
7: ('семь',),
8: ('восемь',),
9: ('девять',),
}
ONES = {
1: ('один',),
2: ('два',),
3: ('три',),
4: ('четыре',),
5: ('пять',),
6: ('шесть',),
7: ('семь',),
8: ('восемь',),
9: ('девять',),
}
TENS = {
0: ('десять',),
1: ('одиннадцать',),
2: ('двенадцать',),
3: ('тринадцать',),
4: ('четырнадцать',),
5: ('пятнадцать',),
6: ('шестнадцать',),
7: ('семнадцать',),
8: ('восемнадцать',),
9: ('девятнадцать',),
}
TWENTIES = {
2: ('двадцать',),
3: ('тридцать',),
4: ('сорок',),
5: ('пятьдесят',),
6: ('шестьдесят',),
7: ('семьдесят',),
8: ('восемьдесят',),
9: ('девяносто',),
}
HUNDREDS = {
1: ('сто',),
2: ('двести',),
3: ('триста',),
4: ('четыреста',),
5: ('пятьсот',),
6: ('шестьсот',),
7: ('семьсот',),
8: ('восемьсот',),
9: ('девятьсот',),
}
THOUSANDS = {
1: ('тысяча', 'тысячи', 'тысяч'), # 10^3
2: ('миллион', 'миллиона', 'миллионов'), # 10^6
3: ('миллиард', 'миллиарда', 'миллиардов'), # 10^9
4: ('триллион', 'триллиона', 'триллионов'), # 10^12
5: ('квадриллион', 'квадриллиона', 'квадриллионов'), # 10^15
6: ('квинтиллион', 'квинтиллиона', 'квинтиллионов'), # 10^18
7: ('секстиллион', 'секстиллиона', 'секстиллионов'), # 10^21
8: ('септиллион', 'септиллиона', 'септиллионов'), # 10^24
9: ('октиллион', 'октиллиона', 'октиллионов'), # 10^27
10: ('нониллион', 'нониллиона', 'нониллионов'), # 10^30
}
class Num2Word_RU(Num2Word_Base):
CURRENCY_FORMS = {
'RUB': (
('рубль', 'рубля', 'рублей'), ('копейка', 'копейки', 'копеек')
),
'EUR': (
('евро', 'евро', 'евро'), ('цент', 'цента', 'центов')
),
}
def setup(self):
self.negword = "минус"
self.pointword = "запятая"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1:
form = 0
elif 5 > n % 10 > 1:
form = 1
else:
form = 2
else:
form = 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _cents_verbose(self, number, currency):
return self._int2word(number, currency == 'RUB')
def _int2word(self, n, feminine=False):
if n < 0:
return ' '.join([self.negword, self._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:
ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES
words.append(ones[n1][0])
if i > 0 and x != 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitbyx
ZERO = ('ноль',)
ONES_FEMININE = {
1: ('одна',),
2: ('две',),
3: ('три',),
4: ('четыре',),
5: ('пять',),
6: ('шесть',),
7: ('семь',),
8: ('восемь',),
9: ('девять',),
}
ONES = {
1: ('один',),
2: ('два',),
3: ('три',),
4: ('четыре',),
5: ('пять',),
6: ('шесть',),
7: ('семь',),
8: ('восемь',),
9: ('девять',),
}
TENS = {
0: ('десять',),
1: ('одиннадцать',),
2: ('двенадцать',),
3: ('тринадцать',),
4: ('четырнадцать',),
5: ('пятнадцать',),
6: ('шестнадцать',),
7: ('семнадцать',),
8: ('восемнадцать',),
9: ('девятнадцать',),
}
TWENTIES = {
2: ('двадцать',),
3: ('тридцать',),
4: ('сорок',),
5: ('пятьдесят',),
6: ('шестьдесят',),
7: ('семьдесят',),
8: ('восемьдесят',),
9: ('девяносто',),
}
HUNDREDS = {
1: ('сто',),
2: ('двести',),
3: ('триста',),
4: ('четыреста',),
5: ('пятьсот',),
6: ('шестьсот',),
7: ('семьсот',),
8: ('восемьсот',),
9: ('девятьсот',),
}
THOUSANDS = {
1: ('тысяча', 'тысячи', 'тысяч'), # 10^3
2: ('миллион', 'миллиона', 'миллионов'), # 10^6
3: ('миллиард', 'миллиарда', 'миллиардов'), # 10^9
4: ('триллион', 'триллиона', 'триллионов'), # 10^12
5: ('квадриллион', 'квадриллиона', 'квадриллионов'), # 10^15
6: ('квинтиллион', 'квинтиллиона', 'квинтиллионов'), # 10^18
7: ('секстиллион', 'секстиллиона', 'секстиллионов'), # 10^21
8: ('септиллион', 'септиллиона', 'септиллионов'), # 10^24
9: ('октиллион', 'октиллиона', 'октиллионов'), # 10^27
10: ('нониллион', 'нониллиона', 'нониллионов'), # 10^30
}
class Num2Word_RU(Num2Word_Base):
CURRENCY_FORMS = {
'RUB': (
('рубль', 'рубля', 'рублей'), ('копейка', 'копейки', 'копеек')
),
'EUR': (
('евро', 'евро', 'евро'), ('цент', 'цента', 'центов')
),
}
def setup(self):
self.negword = "минус"
self.pointword = "запятая"
def set_numwords(self):
# @FIXME
self.cards[0] = []
def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
self._int2word(int(right))
)
else:
return self._int2word(int(n))
def pluralize(self, n, forms):
if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1:
form = 0
elif 5 > n % 10 > 1:
form = 1
else:
form = 2
else:
form = 2
return forms[form]
def to_ordinal(self, number):
raise NotImplementedError()
def _cents_verbose(self, number, currency):
return self._int2word(number, currency == 'RUB')
def _int2word(self, n, feminine=False):
if n < 0:
return ' '.join([self.negword, self._int2word(abs(n))])
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
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:
ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES
words.append(ones[n1][0])
if i > 0 and x != 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)

184
num2words/lang_TH.py Normal file
View File

@@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
from __future__ import unicode_literals
from num2words.base import Num2Word_Base
from num2words.currency import parse_currency_parts
from num2words.utils import splitbyx
class Num2Word_TH(Num2Word_Base):
def setup(self):
self.negword = 'ติดลบ'
self.pointword = 'จุด'
self.CURRENCY_FORMS = {
'THB': (('บาท', 'บาท'), ('สตางค์', 'สตางค์')),
'USD': (('ดอลลาร์', 'ดอลลาร์'), ('เซนต์', 'เซนต์')),
'EUR': (('ยูโร', 'ยูโร'), ('เซนต์', 'เซนต์')),
}
self.high_numwords = []
self.mid_numwords = ['', 'สิบ', 'ร้อย', 'พัน', 'หมื่น', 'แสน', 'ล้าน']
self.low_numwords = [
'ศูนย์', 'หนึ่ง', 'สอง', 'สาม', 'สี่',
'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า'
]
def set_high_numwords(self, high_numwords):
pass
def set_mid_numwords(self, mid_numwords):
pass
def splitnum(self, six_num):
length = len(six_num) > 1
word_num = ''
for index, num in enumerate(map(int, six_num)):
if num:
if index:
word_num = self.mid_numwords[index] + word_num
if length and num == 1 and index == 0:
word_num += 'เอ็ด'
elif index == 1 and num == 2:
word_num = 'ยี่' + word_num
elif index != 1 or num != 1:
word_num = self.low_numwords[num] + word_num
elif num == 0 and index == 0 and length == 0:
word_num = self.low_numwords[0]
return word_num
def split_six(self, num_txt):
result = splitbyx(num_txt, 6, format_int=False)
result = list(result)[::-1]
number_list = []
for i in result:
number_list.append(i[::-1])
return number_list
def add_text_million(self, word_num):
result = ''
for index, t in enumerate(reversed(word_num)):
if index == 0:
result = t
else:
result = result + 'ล้าน' + t
return result
def round_2_decimal(self, number):
integer, cents, negative = parse_currency_parts(
number, is_int_with_cents=False
)
integer = '{}'.format(integer)
cents = '{}'.format(cents)
if len(cents) < 2:
add_zero = 2 - len(cents)
cents = ('0' * add_zero) + cents
text_num = integer + '.' + cents
return text_num, negative
def left_num_to_text(self, number):
left_num_list = self.split_six(number)
left_text_list = []
for i in left_num_list:
left_text_list.append(self.splitnum(i))
left_text = self.add_text_million(left_text_list)
return left_text
def to_cardinal(self, number):
negative = number < 0
pre, post = self.float2tuple(number)
precision = self.precision
pre = '{}'.format(pre)
post = '{}'.format(post)
if negative:
pre = pre.lstrip('-')
if len(post) < precision:
add_zero = precision - len(post)
post = ('0' * add_zero) + post
result = self.left_num_to_text(pre)
right_text = ''
if not post == '0':
for i in map(int, post):
right_text = right_text + self.low_numwords[i]
result = result + 'จุด' + right_text
if negative:
result = 'ติดลบ' + result
return result
def to_ordinal(self, number):
return self.to_cardinal(number)
def to_currency(self, number, currency='THB'):
number, negative = self.round_2_decimal(number)
split_num = number.split('.')
left_num = split_num[0]
left_text = self.left_num_to_text(left_num)
right_num = split_num[1]
right_text = self.splitnum(right_num[::-1].rstrip('0'))
try:
cr1, cr2 = self.CURRENCY_FORMS[currency]
except KeyError:
raise NotImplementedError(
'Currency code "%s" not implemented for "%s"' %
(currency, self.__class__.__name__))
if right_num == '00':
if currency == 'THB':
result = left_text + cr1[0] + 'ถ้วน'
else:
result = left_text + cr1[0]
else:
if left_num == '0':
result = right_text + cr2[0]
else:
result = left_text + cr1[0] + right_text + cr2[0]
if negative:
result = self.negword + result
return result

View File

@@ -1,178 +1,178 @@
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitby3
ZERO = ('нуль',)
ONES_FEMININE = {
1: ('одна',),
2: ('двi',),
3: ('три',),
4: ('чотири',),
5: ('п\'ять',),
6: ('шiсть',),
7: ('с',),
8: ('вiс',),
9: ('дев\'ять',),
}
ONES = {
1: ('один',),
2: ('два',),
3: ('три',),
4: ('чотири',),
5: ('п\'ять',),
6: ('шiсть',),
7: ('с',),
8: ('вiс',),
9: ('дев\'ять',),
}
TENS = {
0: ('десять',),
1: ('одинадцять',),
2: ('дванадцять',),
3: ('тринадцять',),
4: ('чотирнадцять',),
5: ('п\'ятнадцять',),
6: ('шiстнадцять',),
7: ('сiмнадцять',),
8: ('вiсiмнадцять',),
9: ('дев\'ятнадцять',),
}
TWENTIES = {
2: ('двадцять',),
3: ('тридцять',),
4: ('сорок',),
5: ('п\'ятдесят',),
6: ('шiстдесят',),
7: ('сiмдесят',),
8: ('вiсiмдесят',),
9: ('дев\'яносто',),
}
HUNDREDS = {
1: ('сто',),
2: ('двiстi',),
3: ('триста',),
4: ('чотириста',),
5: ('п\'ятсот',),
6: ('шiстсот',),
7: ('ссот',),
8: ('вiссот',),
9: ('дев\'ятсот',),
}
THOUSANDS = {
1: ('тисяча', 'тисячi', 'тисяч'), # 10^3
2: ('мiльйон', 'мiльйони', 'мiльйонiв'), # 10^6
3: ('мiльярд', 'мiльярди', 'мiльярдiв'), # 10^9
4: ('трильйон', 'трильйони', 'трильйонiв'), # 10^12
5: ('квадрильйон', 'квадрильйони', 'квадрильйонiв'), # 10^15
6: ('квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'), # 10^18
7: ('секстильйон', 'секстильйони', 'секстильйонiв'), # 10^21
8: ('септильйон', 'септильйони', 'септильйонiв'), # 10^24
9: ('октильйон', 'октильйони', 'октильйонiв'), # 10^27
10: ('нонiльйон', 'нонiльйони', 'нонiльйонiв'), # 10^30
}
class Num2Word_UK(Num2Word_Base):
CURRENCY_FORMS = {
'UAH': (
('гривня', 'гривнi', 'гривень'),
('копiйка', 'копiйки', 'копiйок')
),
'EUR': (
('евро', 'евро', 'евро'), ('цент', 'центи', 'центiв')
),
}
def setup(self):
self.negword = "мiнус"
self.pointword = "кома"
def set_numwords(self):
# @FIXME
self.cards[0] = []
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 pluralize(self, n, forms):
if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1:
form = 0
elif 5 > n % 10 > 1:
form = 1
else:
form = 2
else:
form = 2
return forms[form]
def _int2word(self, n, feminine=True):
if n < 0:
return ' '.join([self.negword, self._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(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
def _cents_verbose(self, number, currency):
return self._int2word(number, currency == 'UAH')
def to_ordinal(self, number):
raise NotImplementedError()
# -*- 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
from __future__ import unicode_literals
from .base import Num2Word_Base
from .utils import get_digits, splitbyx
ZERO = ('нуль',)
ONES_FEMININE = {
1: ('одна',),
2: ('двi',),
3: ('три',),
4: ('чотири',),
5: ('п\'ять',),
6: ('шiсть',),
7: ('с',),
8: ('вiс',),
9: ('дев\'ять',),
}
ONES = {
1: ('один',),
2: ('два',),
3: ('три',),
4: ('чотири',),
5: ('п\'ять',),
6: ('шiсть',),
7: ('с',),
8: ('вiс',),
9: ('дев\'ять',),
}
TENS = {
0: ('десять',),
1: ('одинадцять',),
2: ('дванадцять',),
3: ('тринадцять',),
4: ('чотирнадцять',),
5: ('п\'ятнадцять',),
6: ('шiстнадцять',),
7: ('сiмнадцять',),
8: ('вiсiмнадцять',),
9: ('дев\'ятнадцять',),
}
TWENTIES = {
2: ('двадцять',),
3: ('тридцять',),
4: ('сорок',),
5: ('п\'ятдесят',),
6: ('шiстдесят',),
7: ('сiмдесят',),
8: ('вiсiмдесят',),
9: ('дев\'яносто',),
}
HUNDREDS = {
1: ('сто',),
2: ('двiстi',),
3: ('триста',),
4: ('чотириста',),
5: ('п\'ятсот',),
6: ('шiстсот',),
7: ('ссот',),
8: ('вiссот',),
9: ('дев\'ятсот',),
}
THOUSANDS = {
1: ('тисяча', 'тисячi', 'тисяч'), # 10^3
2: ('мiльйон', 'мiльйони', 'мiльйонiв'), # 10^6
3: ('мiльярд', 'мiльярди', 'мiльярдiв'), # 10^9
4: ('трильйон', 'трильйони', 'трильйонiв'), # 10^12
5: ('квадрильйон', 'квадрильйони', 'квадрильйонiв'), # 10^15
6: ('квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'), # 10^18
7: ('секстильйон', 'секстильйони', 'секстильйонiв'), # 10^21
8: ('септильйон', 'септильйони', 'септильйонiв'), # 10^24
9: ('октильйон', 'октильйони', 'октильйонiв'), # 10^27
10: ('нонiльйон', 'нонiльйони', 'нонiльйонiв'), # 10^30
}
class Num2Word_UK(Num2Word_Base):
CURRENCY_FORMS = {
'UAH': (
('гривня', 'гривнi', 'гривень'),
('копiйка', 'копiйки', 'копiйок')
),
'EUR': (
('евро', 'евро', 'евро'), ('цент', 'центи', 'центiв')
),
}
def setup(self):
self.negword = "мiнус"
self.pointword = "кома"
def set_numwords(self):
# @FIXME
self.cards[0] = []
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 pluralize(self, n, forms):
if n % 100 < 10 or n % 100 > 20:
if n % 10 == 1:
form = 0
elif 5 > n % 10 > 1:
form = 1
else:
form = 2
else:
form = 2
return forms[form]
def _int2word(self, n, feminine=True):
if n < 0:
return ' '.join([self.negword, self._int2word(abs(n))])
if n == 0:
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
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(self.pluralize(x, THOUSANDS[i]))
return ' '.join(words)
def _cents_verbose(self, number, currency):
return self._int2word(number, currency == 'UAH')
def to_ordinal(self, number):
raise NotImplementedError()

View File

@@ -1,14 +1,17 @@
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 splitbyx(n, x, format_int=True):
length = len(n)
if length > x:
start = length % x
if start > 0:
result = n[:start]
yield int(result) if format_int else result
for i in range(start, length, x):
result = n[i:i+x]
yield int(result) if format_int else result
else:
yield int(n) if format_int else n
def get_digits(n):
a = [int(x) for x in reversed(list(('%03d' % n)[-3:]))]
return a