Niladry Kar
Niladry Kar

Reputation: 1203

Convert amount to word in Python In Indian Format

How to convert amount to word in Indian?

I was using num2words library but its is presenting wrong set of words while presenting 'lakhs' and 'crores'.

For example:

num2words(903614.55, lang='en-IN') Its printing 'nine hundred and three thousand, six hundred and fourteen point five five'

But actual Indian Amount Presentation should be nine lakhs three thousand six hundred fourteen and five five paisa.

Then I tried the below code:

def num2words(num):
    under_20 = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen']
    tens = ['Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety']
    above_100 = {100: 'Hundred',1000:'Thousand', 100000:'Lakhs', 10000000:'Crores'}

    if num < 20:
         return under_20[num]

    if num < 100:
        return tens[(int)(num/10)-2] + ('' if num%10==0 else ' ' + under_20[num%10])

    # find the appropriate pivot - 'Million' in 3,603,550, or 'Thousand' in 603,550
    pivot = max([key for key in above_100.keys() if key <= num])

    return num2words((int)(num/pivot)) + ' ' + above_100[pivot] + ('' if num%pivot==0 else ' ' + num2words(num%pivot))

But now an error is coming

TypeError : list indices must be integers or slices, not decimal.Decimal

My problem is with decimal numbers, Integer is working fine.

Upvotes: 0

Views: 5381

Answers (4)

Inba R
Inba R

Reputation: 11

If you are having trouble writing out amounts with the currency spelled out, try this:

num2words(amount, lang='en_IN', to='currency', currency='USD')

It uses num2words (imagine a tiny translator for numbers). You simply provide the amount (like 50.75), and optionally the currency (like "USD" for dollars), and the code will write it out for you e.g. "fifty dollars and seventy-five cents"

Upvotes: 1

Vaibhav Garg
Vaibhav Garg

Reputation: 737

The solution is simple, and the mistake is obvious in hindsight.

Just replace en-IN with en_IN in your call to num2words. There is no need for any custom code. I was burnt by this too.

num2words.num2words(123456, lang='en_IN')

returns

one lakh, twenty-three thousand, four hundred and fifty-six

Upvotes: 6

rabbit.aaron
rabbit.aaron

Reputation: 2599

I guess you could just cast it on the first line if you're not handling decimals. You can also use // to do integer division.

import decimal    

def num2words(num):
    num = decimal.Decimal(num)
    decimal_part = num - int(num)
    num = int(num)

    if decimal_part:
        return num2words(num) + " point " + (" ".join(num2words(i) for i in str(decimal_part)[2:]))

    under_20 = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']
    tens = ['Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']
    above_100 = {100: 'Hundred', 1000: 'Thousand', 100000: 'Lakhs', 10000000: 'Crores'}

    if num < 20:
        return under_20[num]

    if num < 100:
        return tens[num // 10 - 2] + ('' if num % 10 == 0 else ' ' + under_20[num % 10])

    # find the appropriate pivot - 'Million' in 3,603,550, or 'Thousand' in 603,550
    pivot = max([key for key in above_100.keys() if key <= num])

    return num2words(num // pivot) + ' ' + above_100[pivot] + ('' if num % pivot==0 else ' ' + num2words(num % pivot))


print(num2words(decimal.Decimal("650958.32")))
# Six Lakhs Fifty Thousand Nine Hundred Fifty Eight point Three Two

Upvotes: 3

prashant
prashant

Reputation: 3328

you can split the decimal and fractional part can call num2word function twice on number and other on fractional part

import math
def num2words(num):
    under_20 = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen']
    tens = ['Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety']
    above_100 = {100: 'Hundred',1000:'Thousand', 100000:'Lakhs', 10000000:'Crores'}

    if num < 20:
         return under_20[(int)(num)]

    if num < 100:
        return tens[(int)(num/10)-2] + ('' if num%10==0 else ' ' + under_20[(int)(num%10)])

    # find the appropriate pivot - 'Million' in 3,603,550, or 'Thousand' in 603,550
    pivot = max([key for key in above_100.keys() if key <= num])

    return num2words((int)(num/pivot)) + ' ' + above_100[pivot] + ('' if num%pivot==0 else ' ' + num2words(num%pivot))

num="5.12"
print(num2words(int(num.split(".")[0])))
print(num2words(int(num.split(".")[1])))

https://ide.geeksforgeeks.org/J7zsZyIT6m

Upvotes: 1

Related Questions