Welcome, guest | Sign In | My Account | Store | Cart
```_known = {
0: 'zero',
1: 'one',
2: 'two',
3: 'three',
4: 'four',
5: 'five',
6: 'six',
7: 'seven',
8: 'eight',
9: 'nine',
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen',
20: 'twenty',
30: 'thirty',
40: 'forty',
50: 'fifty',
60: 'sixty',
70: 'seventy',
80: 'eighty',
90: 'ninety'
}
def _positive_spoken_number(n):
"""Assume n is a positive integer.
>>> _positive_spoken_number(900)
'nine hundred'
>>> _positive_spoken_number(100)
'one hundred'
>>> _positive_spoken_number(100000000000)
'one hundred billion'
>>> _positive_spoken_number(1000000000000)
'one trillion'
>>> _positive_spoken_number(33000000000000)
'thirty-three trillion'
>>> _positive_spoken_number(34954523539)
'thirty-four billion, nine hundred fifty-four million, five hundred twenty-three thousand, five hundred thirty-nine'
"""
#import sys; print >>sys.stderr, n
if n in _known:
return _known[n]
bestguess = str(n)
remainder = 0
if n<=20:
print >>sys.stderr, n, "How did this happen?"
assert 0
elif n < 100:
bestguess= _positive_spoken_number((n//10)*10) + '-' + \
_positive_spoken_number(n%10)
return bestguess
elif n < 1000:
bestguess= _positive_spoken_number(n//100) + ' ' + 'hundred'
remainder = n%100
elif n < 1000000:
bestguess= _positive_spoken_number(n//1000) + ' ' + 'thousand'
remainder = n%1000
elif n < 1000000000:
bestguess= _positive_spoken_number(n//1000000) + ' ' + 'million'
remainder = n%1000000
elif n < 1000000000000:
bestguess= _positive_spoken_number(n//1000000000) + ' ' + 'billion'
remainder = n%1000000000
else:
bestguess= _positive_spoken_number(n//1000000000000)+' '+'trillion'
remainder = n%1000000000000
if remainder:
if remainder >= 100: comma = ','
else:                comma = ''
return bestguess + comma + ' ' + _positive_spoken_number(remainder)
else:
return bestguess

def spoken_number(n):
"""Return the number as it would be spoken, or just str(n) if unknown.
>>> spoken_number(0)
'zero'
>>> spoken_number(1)
'one'
>>> spoken_number(2)
'two'
>>> spoken_number(-2)
'minus two'
>>> spoken_number(42)
'forty-two'
>>> spoken_number(-1011)
'minus one thousand eleven'
>>> spoken_number(1111)
'one thousand, one hundred eleven'
"""
if not isinstance(n, int) and not isinstance(n, long): return n
if n<0:
if n in _known: return _known[n]
else:           return 'minus ' + _positive_spoken_number(-n)
return _positive_spoken_number(n)

_aberrant_plurals = {	'knife' 	: 'knives',
'self'		: 'selves',
'elf'		: 'elves',
'life'		: 'lives',
'hoof'		: 'hooves',
'leaf'		: 'leaves',
'echo'		: 'echoes',
'embargo'	: 'embargoes',
'hero'		: 'heroes',
'potato'	: 'potatoes',
'tomato'	: 'tomatoes',
'torpedo'	: 'torpedoes',
'veto'		: 'vetoes',
'child'		: 'children',
'woman'		: 'women',
'man'		: 'men',
'person'	: 'people',
'goose'		: 'geese',
'mouse'		: 'mice',
'barracks'	: 'barracks',
'deer'		: 'deer',
'nucleus'	: 'nuclei',
'syllabus'	: 'syllabi',
'focus'		: 'foci',
'fungus'	: 'fungi',
'cactus'	: 'cacti',
'phenomenon'	: 'phenomena',
'index'		: 'indices',
'appendix'	: 'appendices',
'criterion'	: 'criteria'
}

def how_many(n, singular, plural=None):
"""Return a string describing a number of thing or things
If plural is not supplied, it is guessed from singular.
Assume that all letters (except maybe the first) are lower case, for now.
@todo: Handle upper-case
>>> how_many(0, 'error')
'zero errors'
>>> how_many(1, 'error')
'one error'
>>> how_many(0, 'zero')
'zero zeroes'
>>> how_many(-99, 'penny')
'minus ninety-nine pennies'
>>> how_many(100, 'fuss')
'one hundred fusses'
>>> how_many(111, 'goose')
'one hundred eleven geese'
>>> how_many(-1, 'Chris', "Chris's")
"minus one Chris's"
"""
try: said = spoken_number(n)
except: said = str(n)
if n == 1:
return said + ' ' + singular
if plural: pass
elif singular in _aberrant_plurals: plural = _aberrant_plurals[singular]
else:
root = singular
post = ''
try:
vowels = 'aeiou'
if singular[-1] == 'y' and singular[-2] not in vowels:
root = singular[:-1]; post = 'ies'
elif singular[-1] == 's':
if singular[-2] in vowels:
if singular[-3:] == 'ius': root = singular[:-2]; post = 'i'
else: root = singular[:-1]; post = 'ses'
else: post = 'es'
elif singular[-1] in 'o' or singular[-2:] in ('ch', 'sh'):
post = 'es'
else:
post = 's'
except:
post = 's'
plural = root + post
return said + ' ' + plural

def _test():
import doctest
return doctest.testmod()

if __name__ == '__main__':
_test()
```

### History

• revision 3 (16 years ago)
• previous revisions are not available