ai-content-maker/.venv/Lib/site-packages/num2words/lang_HE.py

328 lines
11 KiB
Python
Raw Permalink Normal View History

2024-05-03 04:18:51 +03:00
# -*- 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 print_function, unicode_literals
from .base import Num2Word_Base
from .compat import to_s
from .currency import parse_currency_parts
from .utils import get_digits, splitbyx
ZERO = (u'אפס',)
ONES = {
1: (u'אחת', u'אחד', u'אחת', u'אחד',
u'ראשונה', u'ראשון', u'ראשונות', u'ראשונים'),
2: (u'שתיים', u'שניים', u'שתי', u'שני',
u'שנייה', u'שני', u'שניות', u'שניים'),
3: (u'שלוש', u'שלושה', u'שלוש', u'שלושת',
u'שלישית', u'שלישי', u'שלישיות', u'שלישיים'),
4: (u'ארבע', u'ארבעה', u'ארבע', u'ארבעת',
u'רביעית', u'רביעי', u'רביעיות', u'רביעיים'),
5: (u'חמש', u'חמישה', u'חמש', u'חמשת',
u'חמישית', u'חמישי', u'חמישיות', u'חמישיים'),
6: (u'שש', u'שישה', u'שש', u'ששת',
u'שישית', u'שישי', u'שישיות', u'שישיים'),
7: (u'שבע', u'שבעה', u'שבע', u'שבעת',
u'שביעית', u'שביעי', u'שביעיות', u'שביעיים'),
8: (u'שמונה', u'שמונה', u'שמונה', u'שמונת',
u'שמינית', u'שמיני', u'שמיניות', u'שמיניים'),
9: (u'תשע', u'תשעה', u'תשע', u'תשעת',
u'תשיעית', u'תשיעי', u'תשיעיות', u'תשיעיים'),
}
TENS = {
0: (u'עשר', u'עשרה', u'עשר', u'עשרת',
u'עשירית', u'עשירי', u'עשיריות', u'עשיריים'),
1: (u'עשרה', u'עשר'),
2: (u'שתים עשרה', u'שנים עשר'),
}
TWENTIES = {
2: (u'עשרים',),
3: (u'שלושים',),
4: (u'ארבעים',),
5: (u'חמישים',),
6: (u'שישים',),
7: (u'שבעים',),
8: (u'שמונים',),
9: (u'תשעים',),
}
HUNDREDS = {
1: (u'מאה', u'מאת'),
2: (u'מאתיים',),
3: (u'מאות',)
}
THOUSANDS = {
1: (u'אלף',),
2: (u'אלפיים',),
3: (u'אלפים', 'אלפי'),
}
LARGE = {
1: (u'מיליון', u'מיליוני'),
2: (u'מיליארד', u'מיליארדי'),
3: (u'טריליון', u'טריליוני'),
4: (u'קוודריליון', u'קוודריליוני'),
5: (u'קווינטיליון', u'קווינטיליוני'),
6: (u'סקסטיליון', u'סקסטיליוני'),
7: (u'ספטיליון', u'ספטיליוני'),
8: (u'אוקטיליון', u'אוקטיליוני'),
9: (u'נוניליון', u'נוניליוני'),
10: (u'דסיליון', u'דסיליוני'),
11: (u'אונדסיליון', u'אונדסיליוני'),
12: (u'דואודסיליון', u'דואודסיליוני'),
13: (u'טרדסיליון', u'טרדסיליוני'),
14: (u'קווטואורדסיליון', u'קווטואורדסיליוני'),
15: (u'קווינדסיליון', u'קווינדסיליוני'),
16: (u'סקסדסיליון', u'סקסדסיליוני'),
17: (u'ספטנדסיליון', u'ספטנדסיליוני'),
18: (u'אוקטודסיליון', u'אוקטודסיליוני'),
19: (u'נובמדסיליון', u'נובמדסיליוני'),
20: (u'ויגינטיליון', u'ויגינטיליוני')
}
AND = u'ו'
DEF = u'ה'
MAXVAL = int('1' + '0'*66)
def chunk2word(n, i, x, gender='f', construct=False,
ordinal=False, plural=False):
words = []
n1, n2, n3 = get_digits(x)
if n3 > 0:
if construct and n == 100:
words.append(HUNDREDS[n3][1])
elif n3 <= 2:
words.append(HUNDREDS[n3][0])
else:
words.append(ONES[n3][0] + ' ' + HUNDREDS[3][0])
if n2 > 1:
words.append(TWENTIES[n2][0])
if i == 0 or x >= 11:
male = gender == 'm' or i > 0
cop = (2*(construct and i == 0)+4*ordinal+2*plural) * (n < 11)
if n2 == 1:
if n1 == 0:
words.append(TENS[n1][male + cop])
elif n1 == 2:
words.append(TENS[n1][male])
else:
words.append(ONES[n1][male] + ' ' + TENS[1][male])
elif n1 > 0:
words.append(ONES[n1][male + cop])
construct_last = construct and (n % 1000 ** i == 0)
if i == 1:
if x >= 11:
words[-1] = words[-1] + ' ' + THOUSANDS[1][0]
elif n1 == 0:
words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct_last])
elif n1 <= 2:
words.append(THOUSANDS[n1][0])
else:
words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct_last])
elif i > 1:
if x >= 11:
words[-1] = words[-1] + ' ' + LARGE[i - 1][construct_last]
elif n1 == 0:
words.append(TENS[0][1 + 2*construct_last] + ' ' +
LARGE[i - 1][construct_last])
elif n1 == 1:
words.append(LARGE[i - 1][0])
else:
words.append(ONES[n1][1 + 2*(construct_last or x == 2)] + ' ' +
LARGE[i - 1][construct_last])
return words
def int2word(n, gender='f', construct=False,
ordinal=False, definite=False, plural=False):
assert n == int(n)
assert not construct or not ordinal
assert ordinal or (not definite and not plural)
if n >= MAXVAL:
raise OverflowError('abs(%s) must be less than %s.' % (n, MAXVAL))
if n == 0:
if ordinal:
return DEF + ZERO[0]
return ZERO[0]
words = []
chunks = list(splitbyx(str(n), 3))
i = len(chunks)
for x in chunks:
i -= 1
if x == 0:
continue
words += chunk2word(n, i, x, gender=gender, construct=construct,
ordinal=ordinal, plural=plural)
# https://hebrew-academy.org.il/2017/01/30/%D7%95-%D7%94%D7%97%D7%99%D7%91%D7%95%D7%A8-%D7%91%D7%9E%D7%A1%D7%A4%D7%A8%D7%99%D7%9D # noqa
if len(words) > 1:
words[-1] = AND + words[-1]
if ordinal and (n >= 11 or definite):
words[0] = DEF + words[0]
return ' '.join(words)
class Num2Word_HE(Num2Word_Base):
CURRENCY_FORMS = {
'ILS': ((u'שקל', u'שקלים'), (u'אגורה', u'אגורות')),
'EUR': ((u'אירו', u'אירו'), (u'סנט', u'סנטים')),
'USD': ((u'דולר', u'דולרים'), (u'סנט', u'סנטים')),
}
CURRENCY_GENDERS = {
'ILS': ('m', 'f'),
'EUR': ('m', 'm'),
'USD': ('m', 'm'),
}
def __init__(self, makaf='-'):
super(Num2Word_HE, self).__init__()
self.makaf = makaf
def setup(self):
super(Num2Word_HE, self).setup()
self.negword = u'מינוס'
self.pointword = u'נקודה'
self.MAXVAL = MAXVAL
def to_cardinal_float(self, value, gender='f'):
try:
float(value) == value
except (ValueError, TypeError, AssertionError, AttributeError):
raise TypeError(self.errmsg_nonnum % value)
pre, post = self.float2tuple(float(value))
post = str(post)
post = '0'*(self.precision - len(post)) + post
out = [self.to_cardinal(pre, gender=gender)]
if self.precision:
out.append(self.title(self.pointword))
for i in range(self.precision):
curr = int(post[i])
out.append(to_s(self.to_cardinal(curr)))
return ' '.join(out)
def to_cardinal(self, value, gender='f', construct=False):
try:
assert int(value) == value
except (ValueError, TypeError, AssertionError):
# https://hebrew-academy.org.il/2019/12/03/%D7%A2%D7%9C-%D7%94%D7%91%D7%A2%D7%AA-%D7%94%D7%9E%D7%A1%D7%A4%D7%A8-%D7%94%D7%9E%D7%A2%D7%95%D7%A8%D7%91 # noqa
return self.to_cardinal_float(value, gender=gender)
out = ""
if value < 0:
value = abs(value)
out = "%s " % self.negword.strip()
if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
return out + int2word(int(value), gender=gender, construct=construct)
def to_ordinal(self, value, gender='m', definite=False, plural=False):
self.verify_ordinal(value)
if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
return int2word(int(value), gender=gender, ordinal=True,
definite=definite, plural=plural)
def pluralize(self, n, forms, currency=None, prefer_singular=False):
assert n == int(n)
form = 1
if n == 1 or prefer_singular and (
abs(n) >= 11 or n == 0 or currency != 'ILS'):
form = 0
return forms[form]
def to_currency(self, val, currency='ILS', cents=True,
separator=AND, adjective=False,
prefer_singular=False, prefer_singular_cents=False):
left, right, is_negative = parse_currency_parts(val)
if not separator.startswith(' '):
separator = ' ' + separator
try:
cr1, cr2 = self.CURRENCY_FORMS[currency]
except KeyError:
raise NotImplementedError(
'Currency code "%s" not implemented for "%s"' %
(currency, self.__class__.__name__))
minus_str = "%s " % self.negword.strip() if is_negative else ""
try:
gender1, gender2 = self.CURRENCY_GENDERS[currency]
except KeyError:
gender1 = gender2 = ''
money_str = self.to_cardinal(left, gender=gender1,
construct=left == 2)
if cents:
cents_str = self.to_cardinal(right, gender=gender2,
construct=right == 2)
else:
cents_str = self._cents_terse(right, currency)
sep_parts = separator.split()
if sep_parts and sep_parts[-1] == AND:
separator += self.makaf
strings = [
minus_str,
money_str,
self.pluralize(left, cr1, currency=currency,
prefer_singular=prefer_singular),
separator,
cents_str,
self.pluralize(right, cr2, currency=currency,
prefer_singular=prefer_singular_cents)
]
if left == 1:
strings[1], strings[2] = strings[2], strings[1]
if right == 1:
strings[4], strings[5] = strings[5], strings[4]
# In Hebrew the separator is along with the following word
return u'%s%s %s%s%s %s' % tuple(strings)