# Numbers to Strings in Python part 2

After implementing most of the suggestions from the first question, This is the code I got:

from math import log

zero_to_nineteen = ("zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen")

tens = ("zero", "ten", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety")

# Powers of a thousand (US system of naming)
suffixes = ("zero", "thousand", "million", "billion", "trillion",
"octillion", "nonillion", "decillion", "undecillion",
"duodecillion", "tredecillion", "quattuordecillion",
"octodecillion", "novendecillion", "vigintillion",
"unvigintillion", "duovigintillion", "tresvigintillion",
"quattuorvigintillion", "quinquavigintillion", "sesvigintillion",
"septemvigintillion", "octovigintillion", "novemvigintillion",
"trigintillion", "untrigintillion", "duotrigintillion",
"trestrigintilion", "quattuortrigintillion",
"quinquatrigintillion", "sestrigintillion", "septentrigintillion",

def spell_out(number):
"""Returns a string representation of the number, in the US system"""
try:
number = int(number)
except OverflowError:
# This will be triggered with large float values such as 1e584
return "infinity"

if number < 0:
return "negative " + spell_out(-1 * number)

if number < 20:
return zero_to_nineteen[number]

if number < 100:
tens_digit, ones_digit = divmod(number, 10)
return _createNumber(tens[tens_digit], ones_digit, "-")

if number < 1000:
hundreds_digit, rest = divmod(number, 100)
return _createNumber(spell_out(hundreds_digit) + " hundred", rest)

suffix_index = int(log(number, 1000))

if suffix_index < len(suffixes):
suffix_value = 1000 ** suffix_index
prefix, rest = divmod(number, suffix_value)
prefix = spell_out(prefix) + " " + suffixes[suffix_index]
return _createNumber(prefix, rest, ", ")

return "infinity"

def _createNumber(prefix, suffix, seperator=" "):
# Returns a number with given prefix and suffix (if needed)
if not isinstance(prefix, str):
prefix = spell_out(prefix)
return prefix if suffix == 0 else prefix + seperator + spell_out(suffix)


• One tiny nitpick: in the definition of _createNumber, the variable seperator should be spelt separator. – alexwlchan Aug 14 '14 at 13:54
• Your comment this will be triggered with large float values such as 1e584 isn't exactly correct, as you're actually using int instead of float. – James Mertz Aug 14 '14 at 22:57
• 1e584 is a float. int(1e584) will raise a OverflowError. Therefore, I am correct in saying that the error will be triggered with large float arguments. – mleyfman Aug 14 '14 at 23:18

math.log works in floating point and thus has limited precision. On my system at least, your code goes to infinite recursion from spell_out(10**15-1) for example. To avoid this, I would break the number into groups using divmod in a loop.

• Annoyingly enough, I did this for the first attempt, but then received a comment that I shouldn't hand-roll my own log function :| – mleyfman Aug 14 '14 at 15:00

It looks pretty nice! I can only nitpick.

return "negative " + spell_out(-1 * number)

return "negative " + spell_out(-number)

• Use snake case in function names, _create_number instead of _createNumber