Python Application: Converting Numbers to Words

Python Application: Converting Numbers to Words

People learning to program often struggle with how to decompose a problem into the steps necessary to write a program to solve that problem. This is one of a series of posts in which I take a problem and go through my decision-making process that leads to a program.

Problem: Given an integer in the range of 1 to 999, print out the number using word (e.g., 123 = one hundred twenty-three). I assume that you understand statements, conditionals, loops, lists, strings, and functions.

You can find a video with more details at https://www.youtube.com/watch?v=1gAiDtRj4qw.

One way that comes to mind and is easy to understand is this:

def f(num) :
    if num == 1 :
        print("one")
    elif num == 2 :
        print("two")
    elif num == 3 :
        print("three")
    .
    .
    .
    elif num == 999 :
        print("nine hundred ninety-nine")

What’s the problem with this approach? For the interval 1 to 999 I have to have 999 conditionals. For 1 to 1 million I would have to have 1 million conditionals. Surely there is an easy way, right?

Design:

In order to produce a scalable solution, assuming it exists, I start by writing some of the numbers in the range of 1 to 999 as words, looking for patterns.

1 = one
2 = two
3 = three
    .
    .
    .
10 = ten
11 = eleven
12 = twelve
    .
    .
    .
20 = twenty
21 = twenty-one
    .
    .
    .
99 = ninety-nine
100 = one hundred
101 = one hundred one
    .
    .
    .
110 = one hundred ten
111 = one hundred eleven
    .
    .
    .
120 = one hundred twenty
121 = one hundred twenty-one
    .
    .
    .
999 = nine hundred ninety-nine

Is there any kind of pattern here and, if so, are there exceptions to it. The most obvious exception are the teens–11 to 19. Each of these has its own distinct word that I will have to deal with. Except for things containing teens, including numbers like 814, I can use the words “one”, “two”, and so forth if the last digit is a 1, 2, and so forth. This means that I can re-use these words. The three digit numbers also begin with one of these words followed by the word “hundred”.

I can see now that there are three main word classes

  • ones: “one”, “two”, …
  • teens: “eleven”, “twelve”, …
  • tens: “ten”, “twenty”, …

I will need some logic to decide which word classes to use and also whether or not their are compound words requiring a hyphen. By writing out a variety of numbers and their corresponding word representations, I can see that

  • 3-digit numbers are in the hundreds
  • except for the teens, a number without a zero in both the second and third digits will need to be hyphenated
  • if the second digit is a 1 and the third digit is not a 0, then the number is a teen.

Final Program
###    functions    ###
def convert( num ) :
    ones = ["", "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" ]
    # hundreds uses ones class plus "hundred"

    snum = "%03d" % num
    d0 = int(snum[0])
    d1 = int(snum[1])
    d2 = int(snum[2])

    if d0 != 0 :
        word = "%s hundred " % ones[ d0 ]
    else :
        word = ""

    if d1 != 0 and d2 != 0 :
        hyphen = "-"
    else :
        hyphen = ""

    if d1 == 1 and d2 != 0 :
        word = word + teens[ d2 ]   # last two digits 
                                    # are teens
    else :
        word = word + tens[ d1 ] + hyphen + ones[ d2 ]

    return word

####  main  ####

num = int(input("Enter a positive integer with up to three digits:  "))
while 1 <= num and num <= 999 :
    word = convert( num )
    print(word)

    num = int(input("Enter a positive integer with up to three digits:  "))

Comments are closed.