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",
"quadrillion", "quintillion", "sextillion", "septillion",
"octillion", "nonillion", "decillion", "undecillion",
"duodecillion", "tredecillion", "quattuordecillion",
"quinquadecillion", "sedecillion", "septendecillion",
"octodecillion", "novendecillion", "vigintillion",
"unvigintillion", "duovigintillion", "tresvigintillion",
"quattuorvigintillion", "quinquavigintillion", "sesvigintillion",
"septemvigintillion", "octovigintillion", "novemvigintillion",
"trigintillion", "untrigintillion", "duotrigintillion",
"trestrigintilion", "quattuortrigintillion",
"quinquatrigintillion", "sestrigintillion", "septentrigintillion",
"octotrigintillion", "noventrigintillion", "quadragintillion")
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)
I'd like to hear any comments about readability/performance/pythonicity and anything else you can think about that could use improving.
_createNumber
, the variableseperator
should be speltseparator
. \$\endgroup\$this will be triggered with large float values such as 1e584
isn't exactly correct, as you're actually usingint
instead offloat
. \$\endgroup\$