AlexW.H.B.
AlexW.H.B.

Reputation: 1871

how to convert numbers into words while keeping leading zeros?

is there a way to turn numbers, ether in a string, or an int, into words without loosing leading zero's? I'm trying to convert dates and times and phone numbers into words, but the second I convert the string value into an int I lose my leading zeros.

here is my code right now for doing the number to words, and it works great as long as there are no leading zeros. here's an example of my problem... let's say I'm turning a date 08-02-2004 I wan't this to output as zero eight zero two... etc but for me to do that in it's current state I would have to do some round about methods... unless I'm missing something.

units = ["", "one", "two", "three", "four",  "five", 
    "six", "seven", "eight", "nine "]
teens = ["", "eleven", "twelve", "thirteen",  "fourteen", 
    "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ["", "ten", "twenty", "thirty", "forty",
    "fifty", "sixty", "seventy", "eighty", "ninety"]
thousands = ["","thousand", "million",  "billion",  "trillion", 
    "quadrillion",  "quintillion",  "sextillion",  "septillion", "octillion", 
    "nonillion",  "decillion",  "undecillion",  "duodecillion",  "tredecillion", 
    "quattuordecillion",  "sexdecillion",  "septendecillion",  "octodecillion", 
    "novemdecillion",  "vigintillion "]

def numToWords(self, num):
    words = []
    if num == 0:
        words.append("zero")
    else:
        numStr = "%d" % num
        numStrLen = len(numStr)
        groups = (numStrLen + 2) / 3
        numStr = numStr.zfill(groups * 3)
        for i in range(0, groups*3, 3):
            h = int(numStr[i])
            t = int(numStr[i+1])
            u = int(numStr[i+2])
            g = groups - (i / 3 + 1)

            if h >= 1:
                words.append(units[h])
                words.append("hundred")

            if t > 1:
                words.append(tens[t])
                if u >= 1:
                    words.append(units[u])
            elif t == 1:
                if u >= 1:
                    words.append(teens[u])
                else:
                    words.append(tens[t])
            else:
                if u >= 1:
                    words.append(units[u])

            if g >= 1 and (h + t + u) > 0:
                words.append(thousands[g])
    return ' '.join([w for w in words]) 

any help or suggestions on this would be greatly appreciated.

Upvotes: 0

Views: 597

Answers (3)

James Sapam
James Sapam

Reputation: 16940

How about this solution using recursive approach ?

def numToWords(i):
    if i < 20:
        result = 'zero,one,two,three,four,five,six,\
                  seven,eight,nine,ten,eleven,twelve,\
                  thirteen,fourteen,fifteen,sixteen,\
                  seventeen,eighteen,nineteen'.split(',')[i]
    elif i < 100:
        result = ',,twenty,thirty,forty,fifty,sixty,seventy,\
                    eighty,ninety'.split(',')[i//10]
        if i % 10:
            result += ' ' + numToWords(i % 10)
    elif i < 1000:
        result = checkio(i // 100) + ' hundred'
        if i % 100:
            result += ' ' + numToWords(i % 100)
    return result

Upvotes: 0

Kyle G.
Kyle G.

Reputation: 880

When you format your int into a string using %d, it drops any leading zeros. To keep them, you need to specify a minimum number of digits, like this:

numStr = "%03d" % num

This will append leading zeros to any number that has less than 3 digits (making the minimum number of digits 3, in this case). But before you go slapping on leading zeros willy-nilly, you first need to decide how many total digits you want to see.

Upvotes: 1

Hamish
Hamish

Reputation: 23346

Make sure you're supplying a string in the first place and only evaluate as an int when you have to. E.g.:

def numToWords(self, numStr):
    words = []
    if int(numStr) == 0:
        words.append("zero")
    else:
        # no longer needed, it's already a string
        # numStr = "%d" % num
        numStrLen = len(numStr)
        groups = (numStrLen + 2) /
        ...

Upvotes: 1

Related Questions