# [Tutor] literal number (was: dictionaries)

Christian Ebert blacktrash@gmx.net
Wed, 27 Feb 2002 02:17:47 +0100

```Danny Yoo on Thursday, February 21, 2002 21:34:36 :

> Yes, the sort() method of lists does it in-place, so the code above
> wouldn't work.  However, we can fix that.  Here's a function that'll
> return a new sorted list:
>
> ###
> def fsort(L, f=cmp):
>     """A "functional" sort that returns a copy of L, with all its contents
>        sorted out."""
>     L2 = L[:]
^^^
is this just a stylistic convention or does it make a
"functional" difference to L2 = L ?

>     L2.sort(f)
>     return L2
> ###

Hm, you got me addicted to those little functions. So I did
the same with reverse() and used it in one of my first
scripts - one could do all this less verbosely by
considering the number as a number and not a list of chars,
using modulo and so forth; but I'm no math guy, so this is
my approach:

###
def litNum(numstr):
"""Returns a literal representation of a positive number."""

def fReverse(mylist):
"""Returns mylist in reversed order."""
mylist.reverse()
return mylist

if numstr == '0': return 'NAUGHTy professor!'

ones = ('', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine')
tens = ('', None, 'twenty', 'thirty', 'forty',
'fifty', 'sixty', 'seventy', 'eighty', 'ninety')
teenies = ('ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen')
powers = ('thousand', 'million', 'billion', 'trillion',
'quadrillion', 'quintillion', 'sextillion')

# list digits in reverse order:
try: digits = fReverse(map(lambda x: int(x), numstr))
except ValueError: return 'A positive integer please.'

d = len(digits)       # count of digits
digind = range(d)     # list indices of digits

# initialize backward listing of literal representation of digits:
strlist = [None for i in digind]

for i in range(1, d, 3):
strlist[i] = ''
if max(digits[i-1:i+1]) and d > i+1:
strlist[i] = 'and '
if digits[i] == 1:
strlist[i-1] = teenies[digits[i-1]]
else:
strlist[i] = '%s%s' % (strlist[i], tens[digits[i]])
if digits[i] and digits[i-1]:
strlist[i] = '%s-' % strlist[i]

for i in digind:
if strlist[i] == None:
strlist[i] = ones[digits[i]]

try:
for i in range(3, d, 3):
if max(digits[i:i+3]):
strlist[i] = '%s %s ' % (strlist[i], powers[(i-1)/3])
except IndexError:
return 'Number goes beyond sextillions, I don\'t have a name for it.'

for i in range(2, d, 3):
if digits[i]:
strlist[i] = '%s hundred' % strlist[i]
if max(digits[i-2:i]):
strlist[i] = '%s ' % strlist[i]

# concatenate list of strings in right order:
return ''.join(fReverse(strlist))

print litNum(raw_input('Enter a positive number to get its English literal: '))
###

I also made a German version, but hesitate to attack a
French one; e. g. 98 == "quatre-vingt dix-huit" ;-b

Christian
--
Hyperion in Frankfurt
www.tko.ch/blacktrash
www.schauspielfrankfurt.de

```