Skip to content

Instantly share code, notes, and snippets.

@mindcruzer
Created May 9, 2015 05:06
Show Gist options
  • Save mindcruzer/b6dbd69292803cf87140 to your computer and use it in GitHub Desktop.
Save mindcruzer/b6dbd69292803cf87140 to your computer and use it in GitHub Desktop.
Convert a number to its English description
ZERO = "zero"
DIGITS = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
TEENS = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen"]
TENS = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
GROUPS = ["hundred", "thousand", "million", "billion", "trillion"]
def number_to_words(n):
"""
Converts a number, n, into its English description.
n: 0 <= n <= 999999999999999
This works by breaking the number up into groups of three digits from right
to left. Each group of three digits is converted into its english description,
then the appropriate suffix is appended. For example:
=> 1311453
=> 1 | 311 | 453
=> one | three hundred eleven | four hundred fifty three
=> one + million | three hundred eleven + thousand | four hundred fifty three
=> one million, three hundred eleven thousand, four hundred fifty three
ex.
>>> print numbers_to_words(3451432)
>>> three million, four hundred fifty one thousand, four hundred thirty two
"""
if n == 0:
return ZERO
# keep track of which group of three we are on
group_count = 1
word = ""
while n > 0:
# get the next three digits of the number
group = n % 1000
# remove those three digits from the number
n = n // 1000
# now we can process these three digits
digit_count = 1
group_word = ""
while group > 0:
# get the current digit
digit = group % 10
# remove this digit from the number
group = group // 10
# peek at the next digit
next_digit = group % 10
# note which digit we are at in this group of three
group_position = digit_count % 3
if group_position == 1 and next_digit == 1:
# we are on the first digit, but the next digit is a one,
# so we can go ahead and process the first two digits at once
group_word = TEENS[digit]
# make sure we process the third digit next time
group = group // 10
digit_count += 1
elif group_position == 1 and digit > 0:
# first digit (ones)
group_word = DIGITS[digit - 1]
elif group_position == 2 and digit > 0:
# second digit (tens)
group_word = "%s %s" % (TENS[digit - 2], group_word)
elif group_position == 0: # hundreds
# third digit (hundreds)
group_word = "%s %s %s" % (DIGITS[digit - 1], GROUPS[0], group_word)
digit_count += 1
if group_word:
# append the appropriate suffix (ex. thousand, million, etc.)
# the first group doesn't get a suffix
if group_count > 1:
group_word = "%s %s," % (group_word, GROUPS[group_count - 1])
# add this group word to the overall word
word = "%s %s" % (group_word, word)
# on to the next group
group_count += 1
return word.rstrip(', ')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment