Skip to content

Commit

Permalink
Merge pull request #533 from michal-juranyi/sklang
Browse files Browse the repository at this point in the history
Add Slovak language support
  • Loading branch information
mrodriguezg1991 committed Sep 6, 2023
2 parents 872510d + 2da1f92 commit 038bb66
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 2 deletions.
5 changes: 3 additions & 2 deletions num2words/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID,
lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT,
lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR,
lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG,
lang_TH, lang_TR, lang_UK, lang_VI)
lang_RO, lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE,
lang_TG, lang_TH, lang_TR, lang_UK, lang_VI)

CONVERTER_CLASSES = {
'am': lang_AM.Num2Word_AM(),
Expand Down Expand Up @@ -57,6 +57,7 @@
'pl': lang_PL.Num2Word_PL(),
'ro': lang_RO.Num2Word_RO(),
'ru': lang_RU.Num2Word_RU(),
'sk': lang_SK.Num2Word_SK(),
'sl': lang_SL.Num2Word_SL(),
'sr': lang_SR.Num2Word_SR(),
'sv': lang_SV.Num2Word_SV(),
Expand Down
160 changes: 160 additions & 0 deletions num2words/lang_SK.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# -*- coding: 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 __future__ import unicode_literals

from .base import Num2Word_Base
from .utils import get_digits, splitbyx

ZERO = ('nula',)

ONES = {
1: ('jeden', 'jeden', set()),
2: ('dva', 'dve', {1, 3, 5, 7, 9}),
3: ('tri', 'tri', set()),
4: ('štyri', 'štyri', set()),
5: ('päť', 'päť', set()),
6: ('šesť', 'šesť', set()),
7: ('sedem', 'sedem', set()),
8: ('osem', 'osem', set()),
9: ('deväť', 'deväť', set()),
}

TENS = {
0: ('desať',),
1: ('jedenásť',),
2: ('dvanásť',),
3: ('trinásť',),
4: ('štrnásť',),
5: ('pätnásť',),
6: ('šestnásť',),
7: ('sedemnásť',),
8: ('osemnásť',),
9: ('devätnásť',),
}

TWENTIES = {
2: ('dvadsať',),
3: ('tridsať',),
4: ('štyridsať',),
5: ('päťdesiat',),
6: ('šesťdesiat',),
7: ('sedemdesiat',),
8: ('osemdesiat',),
9: ('deväťdesiat',),
}

HUNDREDS = {
1: ('sto',),
2: ('dvesto',),
3: ('tristo',),
4: ('štyristo',),
5: ('päťsto',),
6: ('šesťsto',),
7: ('sedemsto',),
8: ('osemsto',),
9: ('deväťsto',),
}

THOUSANDS = {
1: ('tisíc', 'tisíc', 'tisíc'), # 10^3
2: ('milión', 'milióny', 'miliónov'), # 10^6
3: ('miliarda', 'miliardy', 'miliárd'), # 10^9
4: ('bilión', 'bilióny', 'biliónov'), # 10^12
5: ('biliarda', 'biliardy', 'biliárd'), # 10^15
6: ('trilión', 'trilióny', 'triliónov'), # 10^18
7: ('triliarda', 'triliardy', 'triliárd'), # 10^21
8: ('kvadrilión', 'kvadrilióny', 'kvadriliónov'), # 10^24
9: ('kvadriliarda', 'kvadriliardy', 'kvadriliárd'), # 10^27
10: ('kvintilión', 'kvintillióny', 'kvintiliónov'), # 10^30
}


class Num2Word_SK(Num2Word_Base):
CURRENCY_FORMS = {
'EUR': (
('euro', 'eurá', 'eur'), ('cent', 'centy', 'centov')
),
}

def setup(self):
self.negword = "mínus"
self.pointword = "celých"

def to_cardinal(self, number):
n = str(number).replace(',', '.')
if '.' in n:
left, right = n.split('.')
leading_zero_count = len(right) - len(right.lstrip('0'))
decimal_part = ((ZERO[0] + ' ') * leading_zero_count +
self._int2word(int(right)))
return u'%s %s %s' % (
self._int2word(int(left)),
self.pointword,
decimal_part
)
else:
return self._int2word(int(n))

def pluralize(self, n, forms):
if n == 1:
form = 0
elif 0 < n < 5:
form = 1
else:
form = 2
return forms[form]

def to_ordinal(self, value):
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

if x == 0:
continue

n1, n2, n3 = get_digits(x)

word_chunk = []

if n3 > 0:
word_chunk.append(HUNDREDS[n3][0])

if n2 > 1:
word_chunk.append(TWENTIES[n2][0])

if n2 == 1:
word_chunk.append(TENS[n1][0])
elif n1 > 0 and not (i > 0 and x == 1):
if n2 == 0 and n3 == 0 and i in ONES[n1][2]:
word_chunk.append(ONES[n1][1])
else:
word_chunk.append(ONES[n1][0])
if i > 1 and word_chunk:
word_chunk.append(' ')
if i > 0:
word_chunk.append(self.pluralize(x, THOUSANDS[i]))
words.append(''.join(word_chunk))

return ' '.join(words[:-1]) + ''.join(words[-1:])
98 changes: 98 additions & 0 deletions tests/test_sk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

# -*- 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 unittest import TestCase

from num2words import num2words


class Num2WordsSKTest(TestCase):
def test_cardinal(self):
self.assertEqual(num2words(100, lang='sk'), "sto")
self.assertEqual(num2words(101, lang='sk'), "stojeden")
self.assertEqual(num2words(110, lang='sk'), "stodesať")
self.assertEqual(num2words(115, lang='sk'), "stopätnásť")
self.assertEqual(num2words(123, lang='sk'), "stodvadsaťtri")
self.assertEqual(num2words(1000, lang='sk'), "tisíc")
self.assertEqual(num2words(1001, lang='sk'), "tisícjeden")
self.assertEqual(num2words(2012, lang='sk'), "dvetisícdvanásť")
self.assertEqual(
num2words(10.02, lang='sk'),
"desať celých nula dva"
)
self.assertEqual(
num2words(15.007, lang='sk'),
"pätnásť celých nula nula sedem"
)
self.assertEqual(
num2words(12519.85, lang='sk'),
"dvanásťtisícpäťstodevätnásť celých osemdesiatpäť"
)
self.assertEqual(
num2words(123.50, lang='sk'),
"stodvadsaťtri celých päť"
)
self.assertEqual(
num2words(1234567890, lang='sk'),
"miliarda dvestotridsaťštyri miliónov päťstošesťdesiat"
"sedemtisícosemstodeväťdesiat"
)
self.assertEqual(
num2words(215461407892039002157189883901676, lang='sk'),
"dvestopätnásť kvintiliónov štyristošesťdesiatjeden kvadriliárd "
"štyristosedem kvadriliónov osemstodeväťdesiatdva triliárd "
"tridsaťdeväť triliónov dve biliardy stopäťdesiatsedem biliónov "
"stoosemdesiatdeväť miliárd osemstoosemdesiattri miliónov "
"deväťstojedentisícšesťstosedemdesiatšesť"
)
self.assertEqual(
num2words(719094234693663034822824384220291, lang='sk'),
"sedemstodevätnásť kvintiliónov deväťdesiatštyri kvadriliárd "
"dvestotridsaťštyri kvadriliónov šesťstodeväťdesiattri triliárd "
"šesťstošesťdesiattri triliónov tridsaťštyri biliárd "
"osemstodvadsaťdva biliónov osemstodvadsaťštyri miliárd "
"tristoosemdesiatštyri miliónov "
"dvestodvadsaťtisícdvestodeväťdesiatjeden"
)

def test_to_ordinal(self):
# @TODO: implement to_ordinal
with self.assertRaises(NotImplementedError):
num2words(1, lang='sk', to='ordinal')

def test_currency(self):
self.assertEqual(
num2words(10.0, lang='sk', to='currency', currency='EUR'),
"desať eur, nula centov")
self.assertEqual(
num2words(1234.56, lang='sk', to='currency', currency='EUR'),
"tisícdvestotridsaťštyri eur, päťdesiatšesť centov")
self.assertEqual(
num2words(101.11, lang='sk', to='currency', currency='EUR',
separator=' a'),
"stojeden eur a jedenásť centov")
self.assertEqual(
num2words(-12519.85, lang='sk', to='currency', cents=False),
"mínus dvanásťtisícpäťstodevätnásť eur, 85 centov"
)
self.assertEqual(
num2words(19.50, lang='sk', to='currency', cents=False),
"devätnásť eur, 50 centov"
)

0 comments on commit 038bb66

Please sign in to comment.