Categories
Programming

Converting a number into words, this time with Python and inflect.py

Teaching a person how to spell out numbers involves a lot of repetition. Tampa Bay’s own Jack Hartmann, whose children’s educational YouTube channel has over a million subscribers and 300 million views, knows this. He’s got a video that teaches kids the words for the numbers 0 through 10:

Don’t underestimate the power of videos for kids — Jack’s laughing all the way to the bank. This online estimator says that his YouTube channel should be earning about $70,000 every month, and keep in mind that his particular line of work has probably benefited from everyone being stuck at home. I may have to do something similar with the accordion when this software fad passes.

If you just wanted to be able to convert any number from 0 through 10 into word form in Python, you could use a list…

number_words = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']

…and if you wanted the number 3 in word form, you’d use this:

# This is in the Python REPL
>>> number_words[3]
'three'

You wouldn’t want to take this approach for a larger set of numbers, and you probably wouldn’t want to code it yourself. Luckily, you don’t have to do this in Python, thanks to the inflect.py module.

Using inflect.py

Pythoninflect.py is a module that does all sorts of processing to make your programs’ text output grammatically correct. If you hate seeing output like this…

You have 1 items in your cart.

…or this…

You have a egg in your inventory.

…you can use inflect.py to automatically use the correct singular or plural form, use “a” or “an” when appropriate, and so much more.

(I’ll cover inflect.py in greater detail in a future article.)

In addition to all these grammatical goodies, inflect.py can also be used to convert numbers to words.

To use inflect.py, you’ll need to install it first. The simplest way to do so is with pip:

pip install inflect

Once installed, you can use it in your Python programs. Here’s an example:

import inflect

inflector = inflect.engine()

words = inflector.number_to_words(54321)
print(words)

It produces this output:

fifty-four thousand, three hundred and twenty-one

The number_to_words() method has a number of optional parameters that are useful in certain circumstances. For instance, there’s the boolean wantlist parameter, which causes the word output to be broken into “chunks”:

words = inflector.number_to_words(54321, wantlist=True)

It produces this output:

[‘fifty-four thousand’, ‘three hundred and twenty-one’]

Suppose you want the number to be converted into its individual digits as words. You’d use the group parameter:

# This is in the Python REPL

>>> inflector.number_to_words(54321, group=1)
'five, four, three, two, one'

>>> inflector.number_to_words(54321, group=2)
'fifty-four, thirty-two, one'

>>> inflector.number_to_words(54321, group=3)
'five forty-three, twenty-one'

What if you’re using the group parameter set to 1, but want to get all UK English and have it use the word “naught” for zero? Or maybe you want your program to sound like a film noir gangster and say “zip” instead? Or you want it recite a phone number and say “oh”? That’s what the zero parameter is for:

# This is in the Python REPL

>>> inflector.number_to_words(13057, group=1, zero='naught')
'one, three, naught, five, seven'

>>> inflector.number_to_words(13057, group=1, zero='zip')
'one, three, zip, five, seven'

>>> inflector.number_to_words(8675309, group=1, zero='oh')
'eight, six, seven, five, three, oh, nine'

The one parameter does the same thing, but for the digit 1:

# This is in the Python REPL

>>> inflector.number_to_words(13057, group=1, one='unity')
'unity, three, zero, five, seven'

Want to get all Star Trek? Use the decimal parameter to change the default decimal word to “mark”.

# This is in the Python REPL

>>> coordinates = inflector.number_to_words(123.789, group=1, decimal='mark')
>>> print(f"Ensign Crusher, set course to {coordinates}. Engage.")
Ensign Crusher, set course to one, two, three, mark, seven, eight, nine. Engage.

A lot of style guides tell you to spell out the numbers zero through ten, and use the number form for numbers 11 and greater. The threshold parameter makes this easy:

# This is in the Python REPL

>>> inflector.number_to_words(9, threshold=10)
'nine'

>>> inflector.number_to_words(10, threshold=10)
'ten'

>>> inflector.number_to_words(11, threshold=10)
'11'

Go ahead — import inflect.py and play with it. There’s a lot of power in that module, and it goes way beyond just converting words to numbers!

Also worth checking out

If you’re an iOS/macOS programmer, you’ll want to look at this article from a couple of days ago, Convert a number into words in a couple of lines of Swift.