Skip to content

Commit

Permalink
Merge pull request #506 from SkiBY/by_language_added
Browse files Browse the repository at this point in the history
Lang By(Belarusian)  Added
  • Loading branch information
mrodriguezg1991 authored Oct 17, 2023
2 parents 305242f + 54b9701 commit d7d80f2
Show file tree
Hide file tree
Showing 7 changed files with 705 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a
* ``am`` (Amharic)
* ``ar`` (Arabic)
* ``az`` (Azerbaijani)
* ``by`` (Belarusian)
* ``cz`` (Czech)
* ``de`` (German)
* ``dk`` (Danish)
Expand Down
2 changes: 1 addition & 1 deletion bin/num2words
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import sys
from docopt import docopt
import num2words

__version__ = "0.5.12"
__version__ = "0.5.13"
__license__ = "LGPL"


Expand Down
5 changes: 3 additions & 2 deletions num2words/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

from __future__ import unicode_literals

from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN,
lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO,
from . import (lang_AM, lang_AR, lang_AZ, lang_BY, lang_CZ, lang_DE, lang_DK,
lang_EN, lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO,
lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR,
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,
Expand All @@ -30,6 +30,7 @@
'am': lang_AM.Num2Word_AM(),
'ar': lang_AR.Num2Word_AR(),
'az': lang_AZ.Num2Word_AZ(),
'by': lang_BY.Num2Word_BY(),
'cz': lang_CZ.Num2Word_CZ(),
'en': lang_EN.Num2Word_EN(),
'en_IN': lang_EN_IN.Num2Word_EN_IN(),
Expand Down
337 changes: 337 additions & 0 deletions num2words/lang_BY.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
# 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)
4 changes: 4 additions & 0 deletions num2words/lang_RU.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ class Num2Word_RU(Num2Word_Base):
'UZS': (
('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов')
),
'PLN': (
('польский злотый', 'польских слотых', 'польских злотых'),
('грош', 'гроша', 'грошей')
),
}

def setup(self):
Expand Down
Loading

0 comments on commit d7d80f2

Please sign in to comment.