-2

Here is my code for converting number into English words. Here I have one problem that I can't resolve it. If I input 0, this should give me "zero". However, if I input any multiple of 10, it will give me 'hundred zero' rather than 'hundred'.

If I remove if x == 0: return 'zero', this will give me 'zero' if I input '0'. Therefore, how should I be able to resolve this 'zero' issue?

# Create a function that can spell out in English while inputting a whole number

def spelltowords(x):
    digits_to_nineteen = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
    decades = ['', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']

    if x < 1000000000:
        if x < 100000000:
            if x < 20000000:
                if x < 1000000:
                    if x < 100000:
                        if x < 20000:
                            if x < 1000:
                                if x < 100:
                                    if x < 20:
                                        if x is 0:
                                            if x < 0:
                                                return 'negative' + ' ' + spelltowords(-1*x)
                                            return 'zero'
                                        return digits_to_nineteen[x]
                                    else:
                                        return decades[x // 10] + ' ' + digits_to_nineteen[x % 10]
                                else:
                                    return digits_to_nineteen[x // 100] + ' ' + 'hundred' + ' ' + spelltowords(x % 100)
                            else:
                                return digits_to_nineteen[x // 1000] + ' ' + 'thousand' + ' ' + spelltowords(x % 1000)
                        else:
                            return decades[(x // 1000) // 10] + ' ' + digits_to_nineteen[(x // 1000) % 10] + ' ' + 'thousand' + ' ' + spelltowords(x % 1000)
                    else:
                        return digits_to_nineteen[(x // 1000) // 100] + ' ' + 'hundred' + ' ' + spelltowords((x // 1000) % 100) + ' ' + 'thousand' + ' ' + spelltowords(x % 1000)
                else:
                    return digits_to_nineteen[x // 1000000] + ' ' + 'million' + ' ' + spelltowords(x % 1000000)
            else:
                return decades[(x // 1000000) // 10] + ' ' + digits_to_nineteen[(x // 1000000) % 10] + ' ' + 'million' + ' ' + spelltowords(x % 1000000)
        else:
            return digits_to_nineteen[(x // 1000000) // 100] + ' ' + 'hundred' + ' ' + spelltowords((x // 1000000) % 100)+ ' ' + 'million' + ' ' + spelltowords(x % 1000000)
    else:
        return 'over the limit!'




print(spelltowords(200))

Output from the above code

>>> ================================ RESTART ================================
>>> 
two hundred zero
>>> 
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 1
    This is probably a duplicate question - Does [this question](http://stackoverflow.com/questions/8982163/how-do-i-tell-python-to-convert-integers-into-words) answer your request? – NextInLine Jan 28 '15 at 21:25
  • 2
    hypnotic source code! – dm03514 Jan 28 '15 at 21:36
  • This is a common programming puzzle. After you finish your version, look for a generic algorithm for this and try to implement it in Python. – Paulo Scardine Jan 28 '15 at 21:39

2 Answers2

0

The recursive call spelltowords(x % 100) calls spelltowords with 0 for when x is 200. Calling spelltowords with 0 will return 'zero'. If you really want to keep your current implementation, you could make your current function into a helper function and call it with something like this:

def spelltowords(x):
    if x == 0: return 'Zero'
    if x < 0: return 'Negative ' + spelltowards_helper(-1*x)
    return spelltowards_helper(x)

Then get rid of the x is 0 and x < 0 cases. However, I would suggest trying to figure out a more robust solution. Also, you have an error with those two cases anyway:

if x is 0:
    if x < 0:
        return 'negative' + ' ' + spelltowords(-1*x)
    return 'zero'

The innermost code will never be reached, x cannot be both 0 and less than 0.

  • I understand what you mean, but how should I fix this in a way that is easy to understand the code. Is there anyway I can write this code easily? – Adrian Chan Jan 28 '15 at 23:25
  • You have the right idea it's just implemented in a difficult way. My suggestion is to have a separate function that returns a word representation of only the numbers 0-999. For each thousands place you get the 3 digit number by using x % 1000. Increment an integer to keep track of what thousands place you're in (so 0 is empty, 1 is 'thousand', 2 is 'million', etc.) and print it out each loop. You can move to the next thousands place using integer division: number = number / 1000. The rest is figuring out how to concatenate the strings to be in correct order. – monolyth421 Jan 29 '15 at 03:02
  • Would you mind to show me your explanation in code? Sorry, I feel it would helpful if you can do that. – Adrian Chan Jan 29 '15 at 19:09
-1

Can you use a kwarg? e.g.

def spelltowords(x,inner=False):
    digits_to_nineteen = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
    decades = ['', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']

    if x < 1000000000:
        if x < 100000000:
            if x < 20000000:
                if x < 1000000:
                    if x < 100000:
                        if x < 20000:
                            if x < 1000:
                                if x < 100:
                                    if x < 20:
                                        if x is 0:
                                            if inner:
                                                return ''
                                            else:
                                                return 'zero'
                                        elif x < 0:
                                            return 'negative' + ' ' + spelltowords(-1*x)
                                        else:
                                            return digits_to_nineteen[x]
                                    else:
                                        return decades[x // 10] + ' ' + digits_to_nineteen[x % 10]
                                else:
                                    return digits_to_nineteen[x // 100] + ' ' + 'hundred' + ' ' + spelltowords(x % 100,inner=True)
                            else:
                                return digits_to_nineteen[x // 1000] + ' ' + 'thousand' + ' ' + spelltowords(x % 1000,inner=True)
                        else:
                            return decades[(x // 1000) // 10] + ' ' + digits_to_nineteen[(x // 1000) % 10] + ' ' + 'thousand' + ' ' + spelltowords(x % 1000,inner=True)
                    else:
                        return digits_to_nineteen[(x // 1000) // 100] + ' ' + 'hundred' + ' ' + spelltowords((x // 1000) % 100) + ' ' + 'thousand' + ' ' + spelltowords(x % 1000,inner=True)
                else:
                    return digits_to_nineteen[x // 1000000] + ' ' + 'million' + ' ' + spelltowords(x % 1000000,inner=True)
            else:
                return decades[(x // 1000000) // 10] + ' ' + digits_to_nineteen[(x // 1000000) % 10] + ' ' + 'million' + ' ' + spelltowords(x % 1000000,inner=True)
        else:
            return digits_to_nineteen[(x // 1000000) // 100] + ' ' + 'hundred' + ' ' + spelltowords((x // 1000000) % 100,inner=True)+ ' ' + 'million' + ' ' + spelltowords(x % 1000000,inner=True)
    else:
        return 'over the limit!'




print(spelltowords(200))
Tom
  • 570
  • 5
  • 19
  • I tried your method, but it still gives me "zero" at the end if I input "200" or any number has two zero at the end. Do you have better way to do this? – Adrian Chan Jan 28 '15 at 23:22
  • I edited what I wrote to include the entire code, not a trimmed section. My output is `two hundred `. I also tried it with a handful of other numbers ending in zeros, and they all were clean. – Tom Jan 28 '15 at 23:43