Added support for Hungarian language

This commit is contained in:
Daniel Marai
2020-01-28 17:17:16 +01:00
committed by Ernesto Rodriguez Ortiz
parent ebdb52e55f
commit 4dab316025
5 changed files with 388 additions and 5 deletions

View File

@@ -92,6 +92,7 @@ Besides the numerical argument, there are two main optional arguments.
* ``fr_BE`` (French - Belgium) * ``fr_BE`` (French - Belgium)
* ``fr_DZ`` (French - Algeria) * ``fr_DZ`` (French - Algeria)
* ``he`` (Hebrew) * ``he`` (Hebrew)
* ``hu`` (Hungarian)
* ``id`` (Indonesian) * ``id`` (Indonesian)
* ``it`` (Italian) * ``it`` (Italian)
* ``ja`` (Japanese) * ``ja`` (Japanese)

View File

@@ -19,10 +19,11 @@ from __future__ import unicode_literals
from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN,
lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FI, lang_FR,
lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_ID, lang_IT, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID,
lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV, lang_NL, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_LV,
lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO, lang_RU, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_RO,
lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) lang_RU, lang_SL, lang_SR, lang_TE, lang_TH, lang_TR, lang_UK,
lang_VI)
CONVERTER_CLASSES = { CONVERTER_CLASSES = {
'ar': lang_AR.Num2Word_AR(), 'ar': lang_AR.Num2Word_AR(),
@@ -62,7 +63,8 @@ CONVERTER_CLASSES = {
'tr': lang_TR.Num2Word_TR(), 'tr': lang_TR.Num2Word_TR(),
'nl': lang_NL.Num2Word_NL(), 'nl': lang_NL.Num2Word_NL(),
'uk': lang_UK.Num2Word_UK(), 'uk': lang_UK.Num2Word_UK(),
'te': lang_TE.Num2Word_TE() 'te': lang_TE.Num2Word_TE(),
'hu': lang_HU.Num2Word_HU()
} }

View File

@@ -43,6 +43,7 @@ class Num2Word_EU(Num2Word_Base):
'MXN': (('peso', 'pesos'), GENERIC_CENTS), 'MXN': (('peso', 'pesos'), GENERIC_CENTS),
'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')),
'INR': (('rupee', 'rupees'), ('paisa', 'paise')) 'INR': (('rupee', 'rupees'), ('paisa', 'paise'))
'HUF': (('forint', 'forint'), ('fillér', 'fillér'))
} }
CURRENCY_ADJECTIVES = { CURRENCY_ADJECTIVES = {
@@ -55,6 +56,7 @@ class Num2Word_EU(Num2Word_Base):
'MXN': 'Mexican', 'MXN': 'Mexican',
'RON': 'Romanian', 'RON': 'Romanian',
'INR': 'Indian', 'INR': 'Indian',
'HUF': 'Hungarian'
} }
GIGA_SUFFIX = "illiard" GIGA_SUFFIX = "illiard"

165
num2words/lang_HU.py Normal file
View File

@@ -0,0 +1,165 @@
# -*- 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 division, print_function, unicode_literals
from . import lang_EU
ZERO = 'nulla'
class Num2Word_HU(lang_EU.Num2Word_EU):
GIGA_SUFFIX = "illiárd"
MEGA_SUFFIX = "illió"
def setup(self):
super(Num2Word_HU, self).setup()
self.negword = "mínusz "
self.pointword = "egész"
self.mid_numwords = [(1000, "ezer"), (100, "száz"), (90, "kilencven"),
(80, "nyolcvan"), (70, "hetven"), (60, "hatvan"),
(50, "ötven"), (40, "negyven"), (30, "harminc")]
low_numwords = ["kilenc", "nyolc", "hét", "hat", "öt", "négy", "három",
"kettő", "egy"]
self.low_numwords = (['tizen' + w for w in low_numwords]
+ ['tíz']
+ low_numwords)
self.low_numwords = (['huszon' + w for w in low_numwords]
+ ['húsz']
+ self.low_numwords
+ [ZERO])
self.partial_ords = {
'nulla': 'nullad',
'egy': 'egyed',
'kettő': 'ketted',
'három': 'harmad',
'négy': 'negyed',
'öt': 'ötöd',
'hat': 'hatod',
'hét': 'heted',
'nyolc': 'nyolcad',
'kilenc': 'kilenced',
'tíz': 'tized',
'húsz': 'huszad',
'harminc': 'harmincad',
'negyven': 'negyvened',
'ötven': 'ötvened',
'hatvan': 'hatvanad',
'hetven': 'hetvened',
'nyolcvan': 'nyolcvanad',
'kilencven': 'kilencvened',
'száz': 'század',
'ezer': 'ezred',
'illió': 'milliomod',
'illiárd': 'milliárdod'
}
def to_cardinal(self, value, zero=ZERO):
if int(value) != value:
return self.to_cardinal_float(value)
elif value < 0:
out = self.negword + self.to_cardinal(-value)
elif value == 0:
out = zero
elif zero == '' and value == 2:
out = 'két'
elif value < 30:
out = self.cards[value]
elif value < 100:
out = self.tens_to_cardinal(value)
elif value < 1000:
out = self.hundreds_to_cardinal(value)
elif value < 10**6:
out = self.thousands_to_cardinal(value)
else:
out = self.big_number_to_cardinal(value)
return out
def tens_to_cardinal(self, value):
try:
return self.cards[value]
except KeyError:
return self.cards[value // 10 * 10] + self.to_cardinal(value % 10)
def hundreds_to_cardinal(self, value):
hundreds = value // 100
prefix = "száz"
if hundreds != 1:
prefix = self.to_cardinal(hundreds, zero="") + prefix
postfix = self.to_cardinal(value % 100, zero="")
return prefix + postfix
def thousands_to_cardinal(self, value):
thousands = value // 1000
prefix = "ezer"
if thousands != 1:
prefix = self.to_cardinal(thousands, zero="") + prefix
postfix = self.to_cardinal(value % 1000, zero="")
return prefix + ('' if value <= 2000 or not postfix else '-') + postfix
def big_number_to_cardinal(self, value):
digits = len(str(value))
digits = digits if digits % 3 != 0 else digits - 2
exp = 10 ** (digits // 3 * 3)
rest = self.to_cardinal(value % exp, '')
return (self.to_cardinal(value // exp, '') + self.cards[exp]
+ ('-' + rest if rest else ''))
def to_ordinal(self, value):
if value < 0:
return self.negword + self.to_ordinal(-value)
if value == 1:
return 'első'
elif value == 2:
return 'második'
else:
out = self.to_cardinal(value)
for card_word, ord_word in self.partial_ords.items():
if out[-len(card_word):] == card_word:
out = out[:-len(card_word)] + ord_word
break
return out + 'ik'
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return str(value) + '.'
def to_year(self, val, suffix=None, longval=True):
# suffix is prefix here
prefix = ''
if val < 0 or suffix is not None:
val = abs(val)
prefix = (suffix + ' ' if suffix is not None else 'i. e. ')
return prefix + self.to_cardinal(val)
def to_currency(self, val, currency='HUF', cents=True, separator=',',
adjective=False):
return super(Num2Word_HU, self).to_currency(
val, currency, cents, separator, adjective)
def to_cardinal_float(self, value):
if abs(value) != value:
return self.negword + self.to_cardinal_float(-value)
left, right = str(value).split('.')
return (self.to_cardinal(int(left))
+ ' egész '
+ self.to_cardinal(int(right))
+ ' ' + self.partial_ords[self.cards[10 ** len(right)]])

213
tests/test_hu.py Normal file
View File

@@ -0,0 +1,213 @@
# -*- 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 Num2WordsHUTest(TestCase):
def test_and_join_199(self):
# ref https://github.com/savoirfairelinux/num2words/issues/8
self.assertEqual(num2words(199), "one hundred and ninety-nine")
def test_cardinal(self):
self.assertEqual(
num2words(-1, lang='hu'),
'mínusz egy'
)
self.assertEqual(
num2words(0, lang='hu'),
'nulla'
)
self.assertEqual(
num2words(1, lang='hu'),
'egy'
)
self.assertEqual(
num2words(13, lang='hu'),
'tizenhárom'
)
self.assertEqual(
num2words(22, lang='hu'),
'huszonkettő'
)
self.assertEqual(
num2words(75, lang='hu'),
'hetvenöt'
)
self.assertEqual(
num2words(124, lang='hu'),
'százhuszonnégy'
)
self.assertEqual(
num2words(651, lang='hu'),
'hatszázötvenegy'
)
self.assertEqual(
num2words(2232, lang='hu'),
'kétezer-kétszázharminckettő'
)
self.assertEqual(
num2words(16501, lang='hu'),
'tizenhatezer-ötszázegy'
)
self.assertEqual(
num2words(1900000000000, lang='hu'),
'egybillió-kilencszázmilliárd'
)
self.assertEqual(
num2words(24656451324564987566, lang='hu'),
'huszonnégytrillió-hatszázötvenhatbilliárd-négyszázötvenegybillió'
'-háromszázhuszonnégymilliárd-ötszázhatvannégymillió-'
'kilencszáznyolcvanhétezer-ötszázhatvanhat'
)
def test_ordinal(self):
self.assertEqual(
num2words(0, lang='hu', to='ordinal'),
'nulladik'
)
self.assertEqual(
num2words(1, lang='hu', to='ordinal'),
'első'
)
self.assertEqual(
num2words(2, lang='hu', to='ordinal'),
'második'
)
self.assertEqual(
num2words(-3, lang='hu', to='ordinal'),
'mínusz harmadik'
)
self.assertEqual(
num2words(13, lang='hu', to='ordinal'),
'tizenharmadik'
)
self.assertEqual(
num2words(22, lang='hu', to='ordinal'),
'huszonkettedik'
)
self.assertEqual(
num2words(75, lang='hu', to='ordinal'),
'hetvenötödik'
)
self.assertEqual(
num2words(124, lang='hu', to='ordinal'),
'százhuszonnegyedik'
)
self.assertEqual(
num2words(1532, lang='hu', to='ordinal'),
'ezerötszázharminckettedik'
)
self.assertEqual(
num2words(16501, lang='hu', to='ordinal'),
'tizenhatezer-ötszázegyedik'
)
self.assertEqual(
num2words(458755640120000, lang='hu', to='ordinal'),
'négyszázötvennyolcbillió-hétszázötvenötmilliárd-'
'hatszáznegyvenmillió-százhúszezredik'
)
def test_ordinal_num(self):
self.assertEqual(num2words(10, lang='hu', to='ordinal_num'), '10.')
self.assertEqual(num2words(21, lang='hu', to='ordinal_num'), '21.')
self.assertEqual(num2words(102, lang='hu', to='ordinal_num'), '102.')
self.assertEqual(num2words(73, lang='hu', to='ordinal_num'), '73.')
def test_cardinal_for_float_number(self):
# issue 24
self.assertEqual(num2words(12, lang='hu'),
"tizenkettő")
self.assertEqual(num2words(12.0, lang='hu'),
"tizenkettő")
self.assertEqual(num2words(12.5, lang='hu'),
"tizenkettő egész öt tized")
self.assertEqual(num2words(-12.5, lang='hu'),
"mínusz tizenkettő egész öt tized")
self.assertEqual(num2words(12.51, lang='hu'),
"tizenkettő egész ötvenegy század")
self.assertEqual(num2words(12.53, lang='hu'),
"tizenkettő egész ötvenhárom század")
self.assertEqual(num2words(12.590, lang='hu'),
"tizenkettő egész ötvenkilenc század")
self.assertEqual(num2words(12.005, lang='hu'),
"tizenkettő egész öt ezred")
def test_overflow(self):
with self.assertRaises(OverflowError):
num2words("1000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000")
def test_to_currency(self):
self.assertEqual(
num2words('38.4', lang='hu', to='currency', separator=' és',
cents=False, currency='HUF'),
"harmincnyolc forint és 40 fillér"
)
self.assertEqual(
num2words('0', lang='hu', to='currency', separator=' és',
cents=False, currency='HUF'),
"nulla forint és 00 fillér"
)
self.assertEqual(
num2words('1.01', lang='hu', to='currency', separator=' és',
cents=True, currency='HUF'),
"egy forint és egy fillér"
)
self.assertEqual(
num2words('4778.00', lang='hu', to='currency', separator=' és',
cents=True, currency='HUF', adjective=True),
'négyezer-hétszázhetvennyolc Hungarian forint'
' és nulla fillér')
self.assertEqual(
num2words('4778.00', lang='hu', to='currency', separator=' és',
cents=True, currency='HUF'),
'négyezer-hétszázhetvennyolc forint és nulla fillér')
def test_to_year(self):
# issue 141
# "e2 e2"
self.assertEqual(num2words(1990, lang='hu', to='year'),
'ezerkilencszázkilencven')
self.assertEqual(num2words(5555, lang='hu', to='year'),
'ötezer-ötszázötvenöt')
self.assertEqual(num2words(2020, lang='hu', to='year'),
'kétezer-húsz')
self.assertEqual(num2words(905, lang='hu', to='year'),
'kilencszázöt')
self.assertEqual(num2words(0, lang='hu', to='year'),
'nulla')
# suffixes
self.assertEqual(num2words(-44, lang='hu', to='year'),
'i. e. negyvennégy')
self.assertEqual(num2words(-44, lang='hu', to='year', suffix='Kr. e.'),
'Kr. e. negyvennégy')
self.assertEqual(num2words(1, lang='hu', to='year', suffix='Kr. u.'),
'Kr. u. egy')
self.assertEqual(num2words(-66000000, lang='hu', to='year'),
'i. e. hatvanhatmillió')