tempgen.libs.num2t4ru
Created on 04.07.2011 Changed on 13.03.2016 by Artem Tiumentcev @author: Sergey Prokhorov me@seriyps.ru
View Source
# -*- 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()
View Source
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
Converts numbers from 19 to 999
View Source
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()
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
#  
def
decimal2text(
value,
places=2,
int_units=(('', '', ''), 'm'),
exp_units=(('', '', ''), 'm')
):
View Source
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))