1
0
mirror of https://github.com/janvarev/Irene-Voice-Assistant.git synced 2025-12-02 22:58:35 +02:00
Files
Irene-Voice-Assistant/utils/num_to_text_ru.py
Vladislav Janvarev 70798db62e Initial commit
2021-12-14 12:51:47 +03:00

141 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
'''
Created on 04.07.2011
Changed on 13.03.2016 by Artem Tiumentcev
@author: Sergey Prokhorov <me@seriyps.ru>
'''
import decimal
units = (
u'ноль',
(u'один', u'одна'),
(u'два', u'две'),
u'три', u'четыре', u'пять',
u'шесть', u'семь', u'восемь', u'девять'
)
teens = (
u'десять', u'одиннадцать',
u'двенадцать', u'тринадцать',
u'четырнадцать', u'пятнадцать',
u'шестнадцать', u'семнадцать',
u'восемнадцать', u'девятнадцать'
)
tens = (
teens,
u'двадцать', u'тридцать',
u'сорок', u'пятьдесят',
u'шестьдесят', u'семьдесят',
u'восемьдесят', u'девяносто'
)
hundreds = (
u'сто', u'двести',
u'триста', u'четыреста',
u'пятьсот', u'шестьсот',
u'семьсот', u'восемьсот',
u'девятьсот'
)
orders = (# plural forms and gender
#((u'', u'', u''), 'm'), # ((u'рубль', u'рубля', u'рублей'), 'm'), # ((u'копейка', u'копейки', u'копеек'), 'f')
((u'тысяча', u'тысячи', u'тысяч'), 'f'),
((u'миллион', u'миллиона', u'миллионов'), 'm'),
((u'миллиард', u'миллиарда', u'миллиардов'), 'm'),
)
minus = u'минус'
def thousand(rest, sex):
"""Converts numbers from 19 to 999"""
prev = 0
plural = 2
name = []
use_teens = rest % 100 >= 10 and rest % 100 <= 19
if not use_teens:
data = ((units, 10), (tens, 100), (hundreds, 1000))
else:
data = ((teens, 10), (hundreds, 1000))
for names, x in data:
cur = int(((rest - prev) % x) * 10 / x)
prev = rest % x
if x == 10 and use_teens:
plural = 2
name.append(teens[cur])
elif cur == 0:
continue
elif x == 10:
name_ = names[cur]
if isinstance(name_, tuple):
name_ = name_[0 if sex == 'm' else 1]
name.append(name_)
if cur >= 2 and cur <= 4:
plural = 1
elif cur == 1:
plural = 0
else:
plural = 2
else:
name.append(names[cur-1])
return plural, name
def num2text(num, main_units=((u'', u'', u''), 'm')):
"""
http://ru.wikipedia.org/wiki/Gettext#.D0.9C.D0.BD.D0.BE.D0.B6.D0.B5.D1.81.\
D1.82.D0.B2.D0.B5.D0.BD.D0.BD.D1.8B.D0.B5_.D1.87.D0.B8.D1.81.D0.BB.D0.B0_2
"""
_orders = (main_units,) + orders
if num == 0:
return ' '.join((units[0], _orders[0][0][2])).strip() # ноль
rest = abs(num)
ord = 0
name = []
while rest > 0:
plural, nme = thousand(rest % 1000, _orders[ord][1])
if nme or ord == 0:
name.append(_orders[ord][0][plural])
name += nme
rest = int(rest / 1000)
ord += 1
if num < 0:
name.append(minus)
name.reverse()
return ' '.join(name).strip()
def decimal2text(value, places=2,
int_units=(('', '', ''), 'm'),
exp_units=(('', '', ''), 'm')):
value = decimal.Decimal(value)
q = decimal.Decimal(10) ** -places
integral, exp = str(value.quantize(q)).split('.')
return u'{} {}'.format(
num2text(int(integral), int_units),
num2text(int(exp), exp_units))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
try:
num = sys.argv[1]
if '.' in num:
print(decimal2text(
decimal.Decimal(num),
int_units=((u'штука', u'штуки', u'штук'), 'f'),
exp_units=((u'кусок', u'куска', u'кусков'), 'm')))
else:
print(num2text(
int(num),
main_units=((u'штука', u'штуки', u'штук'), 'f')))
except ValueError:
print (sys.stderr, "Invalid argument {}".format(sys.argv[1]))
sys.exit()