Преобразование суммы в индийскую нотацию в Python

Проблема: мне нужно перевести сумму в формат индийской валюты

Мой код: у меня есть следующая реализация Python:

import decimal
def currencyInIndiaFormat(n):
  d = decimal.Decimal(str(n))
  if d.as_tuple().exponent < -2:
    s = str(n)
  else:
    s = '{0:.2f}'.format(n)
  l = len(s)
  i = l-1;
  res = ''
  flag = 0
  k = 0
  while i>=0:
    if flag==0:
      res = res + s[i]
      if s[i]=='.':
        flag = 1
    elif flag==1:
      k = k + 1
      res = res + s[i]
      if k==3 and i-1>=0:
        res = res + ','
        flag = 2
        k = 0
    else:
      k = k + 1
      res = res + s[i]
      if k==2 and i-1>=0:
        res = res + ','
        flag = 2
        k = 0
    i = i - 1

  return res[::-1]

def main():
  n = 100.52
  print "INR " + currencyInIndiaFormat(n)  # INR 100.52
  n = 1000.108
  print "INR " + currencyInIndiaFormat(n)  # INR 1,000.108
  n = 1200000
  print "INR " + currencyInIndiaFormat(n)  # INR 12,00,000.00

main()

Мой вопрос: есть ли способ сделать мою функцию currencyInIndiaFormat более короткой, краткой и чистой?/Есть ли лучший способ написать мою функцию currencyInIndiaFormat?

Примечание: мой вопрос в основном основан на реализации вышеуказанной проблемы в Python. Это не дубликат ранее заданных вопросов относительно конвертации валюты в индийский формат.

Индийский формат валюты:

Например, числа здесь представлены как:

1
10
100
1,000
10,000
1,00,000
10,00,000
1,00,00,000
10,00,00,000

Обратитесь индийская система нумерации

Ответ 1

Слишком много работы.

>>> import locale
>>> locale.setlocale(locale.LC_MONETARY, 'en_IN')
'en_IN'
>>> print locale.currency(100.52, grouping=True)
₹ 100.52
>>> print locale.currency(1000.108, grouping=True)
₹ 1,000.11
>>> print locale.currency(1200000, grouping=True)
₹ 12,00,000.00

Ответ 2

Я думаю, что это решение достаточно надежное:

from math import log10
def to_indian(amount):
  iamount = int(amount)
  famount = ".%.02" % (famount - iamount)
  if iamount < 1000:
    return str(iamount) + famount
  result = ','.join(reversed([("%02d" % (iamount // 1000 // (10**(2 * k)) % 100)) 
                            for k in range(int(log10(iamount // 1000)) // 2 + 1)]))\
            + ","\
            + ("%03d" % (iamount % 1000))
  return result.lstrip("0") + famount

print(to_indian(555))
# 555.00
print(to_indian(1249821341345))
# 12,49,82,13,41,345.00

Ответ 3

Вы можете следовать этим шагам. Установить пакет Babel Python из pip

pip install Babel

В вашем скрипте Python

from babel.numbers import format_currency
format_currency(5433422.8012, 'INR', locale='en_IN')

Выход:

₹ 54,33,422.80

Ответ 4

Не удалось заставить другие два решения работать на меня, поэтому я сделал что-то более низкотехнологичное:

def format_as_indian(input):
    input_list = list(str(input))
    if len(input_list) <= 1:
        formatted_input = input
    else:
        first_number = input_list.pop(0)
        last_number = input_list.pop()
        formatted_input = first_number + (
            (''.join(l + ',' * (n % 2 == 1) for n, l in enumerate(reversed(input_list)))[::-1] + last_number)
        )

        if len(input_list) % 2 == 0:
            formatted_input.lstrip(',')

    return formatted_input

Это не работает с десятичными знаками. Если вам это нужно, я бы предложил сохранить десятичную часть в другую переменную и добавить ее обратно в конце.

Ответ 5

Вот обратный путь:

import re
def in_for(value):
    value,b=str(value),''
    value=''.join(map(lambda va:va if re.match(r'[0-9,.]',va) else '',value))
    val=value
    if val.count(',')==0:
        v,c,a,cc,ii=val,0,[3,2,2],0,0
        val=val[:val.rfind('.')] if val.rfind('.')>=0  else val
        for i in val[::-1]:
            if c==ii and c!=0:
                ii+=a[cc%3]
                b=','+i+b
                cc+=1  
            else:
                b=i+b
            c+=1
        b=b[1:] if b[0]==',' else b
        val=b+v[value.rfind('.'):]  if value.rfind('.')>=0  else b
    else:
        val=str(val).strip('()').replace(' ','')
    v=val.rfind('.')
    if v>0:
        val=val[:v+3]
    return val.rstrip('0').rstrip('.') if '.' in val else val

print(in_for('1000000000000.5445'))

Выход будет:

10,000,00,00,000.54 

(Как упомянуто в индийской системе счисления в Википедии, например: 67,89,000,00,00,000)