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

338 lines
11 KiB
Python
Raw Permalink Normal View History

2024-05-03 04:18:51 +03:00
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# Copyright (c) 2022, Sergei Ruzki. 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 = {
"f": {
1: "адна",
2: "дзве",
3: "тры",
4: "чатыры",
5: "пяць",
6: "шэсць",
7: "сем",
8: "восем",
9: "дзевяць",
},
"m": {
1: "адзін",
2: "два",
3: "тры",
4: "чатыры",
5: "пяць",
6: "шэсць",
7: "сем",
8: "восем",
9: "дзевяць",
},
"n": {
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_BY(Num2Word_Base):
CURRENCY_FORMS = {
"RUB": (
("расійскі рубель", "расійскія рублі", "расійскіх рублёў"),
("капейка", "капейкі", "капеек"),
),
"EUR": (("еўра", "еўра", "еўра"), ("цэнт", "цэнты", "цэнтаў")),
"USD": (("долар", "долары", "долараў"), ("цэнт", "цэнты", "цэнтаў")),
"UAH": (
("грыўна", "грыўны", "грыўнаў"),
("капейка", "капейкі", "капеек"),
),
"KZT": (("тэнге", "тэнге", "тэнге"), ("тыйін", "тыйіны", "тыйінаў")),
"BYN": (
("беларускі рубель", "беларускія рублі", "беларускіх рублёў"),
("капейка", "капейкі", "капеек"),
),
"UZS": (("сум", "сумы", "сумаў"), ("тыйін", "тыйіны", "тыйінаў")),
}
def setup(self):
self.negword = "мінус"
self.pointword = "коска"
self.ords = {
"нуль": "нулявы",
"адзін": "першы",
"два": "другі",
"тры": "трэці",
"чатыры": "чацвёрты",
"пяць": "пяты",
"шэсць": "шосты",
"сем": "сёмы",
"восем": "восьмы",
"дзевяць": "дзявяты",
"сто": "соты",
"тысяча": "тысячны",
}
self.ords_adjective = {
"адзін": "адна",
"адна": "адна",
"дзве": "двух",
"тры": "трох",
"чатыры": "чатырох",
"пяць": "пяці",
"шэсць": "шасці",
"сем": "сямі",
"восем": "васьмі",
"дзевяць": "дзевяцi",
"сто": "ста",
}
def to_cardinal(self, number, gender="m"):
n = str(number).replace(",", ".")
if "." in n:
left, right = n.split(".")
if set(right) == {"0"}:
leading_zero_count = 0
else:
leading_zero_count = len(right) - len(right.lstrip("0"))
decimal_part = (ZERO + " ") * leading_zero_count + self._int2word(
int(right), gender
)
return "{} {} {}".format(
self._int2word(int(left), gender), self.pointword, decimal_part
)
else:
return self._int2word(int(n), gender)
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, gender="m"):
self.verify_ordinal(number)
outwords = self.to_cardinal(number, gender).split(" ")
lastword = outwords[-1].lower()
try:
if len(outwords) > 1:
if outwords[-2] in self.ords_adjective:
outwords[-2] = self.ords_adjective.get(
outwords[-2], outwords[-2]
)
elif outwords[-2] == "дзесяць":
outwords[-2] = outwords[-2][:-1] + "і"
if len(outwords) == 3:
if outwords[-3] in ["адзін", "адна"]:
outwords[-3] = ""
lastword = self.ords[lastword]
except KeyError:
if lastword[:-3] in self.ords_adjective:
lastword = (
self.ords_adjective.get(lastword[:-3], lastword) + "соты"
)
elif lastword[-5:] == "шэсць":
lastword = "шосты"
elif lastword[-7:] == "дзесяць":
lastword = "дзясяты"
elif lastword[-9:] == "семдзесят":
lastword = "сямідзясяты"
elif lastword[-1] == "ь" or lastword[-2] == "ц":
lastword = lastword[:-2] + "ты"
elif lastword[-1] == "к":
lastword = lastword.replace("о", "а") + "авы"
elif lastword[-2] == "ч" or lastword[-1] == "ч":
if lastword[-2] == "ч":
lastword = lastword[:-1] + "ны"
if lastword[-1] == "ч":
lastword = lastword + "ны"
elif lastword[-1] == "н" or lastword[-2] == "н":
lastword = lastword[: lastword.rfind("н") + 1] + "ны"
elif lastword[-1] == "д" or lastword[-2] == "д":
lastword = lastword[: lastword.rfind("д") + 1] + "ны"
if gender == "f":
if lastword[-2:] in [
"ці",
]:
lastword = lastword[:-2] + "цяя"
else:
lastword = lastword[:-1] + "ая"
if gender == "n":
if lastword[-2:] in [
"ці", "ца"
]:
lastword = lastword[:-2] + "цяе"
else:
lastword = lastword[:-1] + "ае"
outwords[-1] = self.title(lastword)
if len(outwords) == 2 and "адна" in outwords[-2]:
outwords[-2] = outwords[-1]
del outwords[-1]
if len(outwords) > 2 and "тысяч" in outwords[-1]:
if 'сорак' in outwords[-3]:
outwords[-3] = outwords[-3].replace('сорак', 'сарака')
outwords[-3] = outwords[-3] + outwords[-2] + outwords[-1]
del outwords[-1]
del outwords[-1]
elif len(outwords) > 1 and "тысяч" in outwords[-1]:
outwords[-2] = outwords[-2] + outwords[-1]
del outwords[-1]
return " ".join(outwords).strip()
def _money_verbose(self, number, currency):
gender = "m"
if currency == "UAH":
gender = "f"
return self._int2word(number, gender)
def _cents_verbose(self, number, currency):
if currency in ("UAH", "RUB", "BYN"):
gender = "f"
else:
gender = "m"
return self._int2word(number, gender)
def _int2word(self, n, gender="m"):
if isinstance(gender, bool) and gender:
gender = "f"
if n < 0:
return " ".join([self.negword, self._int2word(abs(n), gender)])
if n == 0:
return ZERO
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)
if n3 > 0:
words.append(HUNDREDS[n3])
if n2 > 1:
words.append(TWENTIES[n2])
if n2 == 1:
words.append(TENS[n1])
elif n1 > 0:
if i == 0:
ones = ONES[gender]
elif i == 1:
ones = ONES["f"] # Thousands are feminine
else:
ones = ONES["m"]
words.append(ones[n1])
if i > 0:
words.append(self.pluralize(x, THOUSANDS[i]))
return " ".join(words)