On 07/06/2013 10:40 PM, Jim Mooney wrote:
On 6 July 2013 19:09, Dave Angel <[email protected]> wrote:

           <SNIP>

If you'd like, I'll post my full version, changed as little as possible from

That would be helpful. The corrections are already four times the size
of the program, and at least three pots of coffee ;')


I hope this is useful. There are lots more places where I might clean things up, but I wanted to make it as close to yours as possible, so you could reasonably diff the two.

# Using C:\Python33\python.exe on Win 7 in c:\python33\jimprogs - not
#Windows-specific
# Also works with python 2.7


import sys
import random


#No need to check version, just try to use raw_input.  If it's not defined,
#  then input should already work
try:
    input = raw_input
except NameError as e:
    pass      #we must be on version 3.0 or larger

try:
    range = xrange
except NameError as e:
    pass  #we must be on version 3.0 or larger

# Data
ones = {'1': 'one', '2': 'two', '3': 'three', '4': 'four', '5': 'five',
'6': 'six',
'7': 'seven', '8': 'eight', '9': 'nine'}

tens = {'2': 'twenty', '3': 'thirty', '4': 'forty', '5': 'fifty', '6':
'sixty',
'7': 'seventy', '8': 'eighty', '9': 'ninety'}

doubles = {'0': 'ten', '1': 'eleven', '2': 'twelve', '3': 'thirteen', '4':
'fourteen',
'5': 'fifteen', '6': 'sixteen', '7': 'seventeen', '8': 'eighteen', '9':
'nineteen'}

powers_of_1000 = (' thousand', ' million', ' billion', ' trillion',
' quadrillion', ' quintillion', ' sextillion', ' septillion', ' octillion',
' nonillion', ' decillion')

'''add these later, and also option for dollars-and-cents ending.
'vigintillion', 'novemdecillion', 'octodecillion', 'septendecillion',
'sexdecillion', 'quindecillion', 'quattuordecillion', 'tredecillion',
'duodecillion', 'undecillion',
'decillion', 'nonillion'
'''

# Functions
def get_raw_input():
    '''Enter a positive integer. A list of triplets in the same order will
be returned.
    Raise ValueError to loop on non-integer input, or return 'zero'
trigger-value of
    'xxx' if all zeroes are entered. If input is okay, strip leading
zeroes, then
    zero-pad leftmost triplet to three characters, so all slices are
triplets. Adjust
    input for different Python versions.'''
    while True:
        try:
            if sys.version[0:3] == '2.7':
numbers_str = original = raw_input('Enter a positive integer, space \
separated if desired.')
            elif sys.version[0:3] == '3.3':
numbers_str = original = input('Enter a positive integer, space \
separated if desired.')
            else:
                print('Python versions 2.7 and 3.3 only supported')
                sys.exit()

            numbers_str = ''.join(numbers_str.split())
            if numbers_str == '' or numbers_str == ' ': raise ValueError

#NO POINT in special-casing zero. It's a perfectly valid value.
            #numbers_int = int(numbers_str)
            #if numbers_int == 0:
            #    print('Zero')
            #    sys.exit()

            numbers_str = str(int(numbers_str)) #normalize it
            if len(numbers_str) > 36: raise ArithmeticError
            break
        except KeyboardInterrupt:
            print('Program cancelled by user')
            sys.exit()
        except ValueError as err:
            print(original, "is not an integer.")
            continue
        except ArithmeticError as err:
print(original, "is too big.\n999...decillion is max: 10**37-1 or 36 chars \
or 12 groups of 3 chars")
    return numbers_str

def make_triplets_from_input(numbers_str):
    leftpad = "0" * ((-len(numbers_str))%3)
    numbers_str = leftpad + numbers_str
    #print "numbers_str:", numbers_str
    triplets = [numbers_str[x:x+3] for x in range(0,len(numbers_str),3)]
    #print "triplets are", triplets
    return triplets

def numbers_to_name(triplets):
    '''Create a name from each triplet and append the power of ten'''
    if triplets == ["000"]:
        return "zero"
    triplen = len(triplets) - 2
    number_name = ''

    #print "triplets are", triplets
    for triplet in triplets:
        #print "triplet is", triplet
        triplet_name = ''
        first, second, third, last_two = (triplet[0], triplet[1],
triplet[2], triplet[1:])
        if triplet == '000':
            triplen -= 1
            continue
        if first > '0':
if last_two == '00': # special case - snip extra space separator
                triplet_name += ones.get(first) + ' hundred'
            else:
                triplet_name += ones.get(first) + ' hundred '
        if second == '0':
            if third > '0':
                triplet_name += ones.get(third)
        elif second == '1':
            triplet_name += doubles.get(third)
        elif second > '1':
            triplet_name += tens.get(second)
            if third > '0':
                triplet_name += '-' + ones.get(third)
        number_name += triplet_name
        if triplen > -1:
            number_name += powers_of_1000[triplen] + ', '
        triplen -= 1
    if number_name[-2] == ',':
number_name = number_name[0:-2] # special case - snip extraneous ending comma
    return number_name

def int_name(i):
    triplets = make_triplets_from_input(str(i))
    return numbers_to_name(triplets)

# Main Program - turn numeric input into number-names
if __name__ == '__main__':
    if False:
        raw = get_raw_input()
        triplets = make_triplets_from_input(raw)
        print(numbers_to_name(triplets))



    from vegaseat import int2word

    def compare_em(i):
        a = int_name(i).replace("-", " ").replace(",", "")
        b = int2word(i).strip()
        if b == "": b = "zero"
        if a !=b:
            print(i, a, b)
            input("  press Enter to continue  ")

    for i in range(200001):
        compare_em(i)

    #The following shows a place where the vegaseat code
    # starts getting buggy.  In particular, it doesn't handle
    # numbers bigger than 999octillion or so.
    #Note, if we make a range starting at 10**30,
    # we get OverflowError, so we fake it
    start = 10**30 - 2
    for cntr in range(5):
        i = start + cntr
        compare_em(i)

    print "now starting random tests"
    for j in range(1000000):
exponent = random.randint(4, 30) #It appears that vegaseat is buggy beyond 999octillion
        i = random.randint(0, 10**exponent-1)
        compare_em(i)





--
DaveA

_______________________________________________
Tutor maillist  -  [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to