#!/usr/bin/env python
'''
$Id$

cardrun.py -- "credit card run" script serves as a demo for a
    ficticious credit card transaction processing application
    which reads data in from a file and uses the safe_float()
    function along with try-except to safely "ignore bad data" 
    such as string text as opposed to strictly numerical input.
'''

# import sys and types modules
import sys
import types

# safe_float() --> float
def safe_float(object):
    'safe_float() converts strings to floats "safely"'

    # attempt to convert object using float()
    try:
        retval = float(object)

    # failure return value is error reason
    except (TypeError, ValueError), exc:
        retval = exc[-1] 

    return retval


# main() --> None
def main():
    'main() handles all the data processing'

    # attempt to open data file
    try:
        ccfile = open('ccdata.txt')

    # display error reason on failure
    except IOError, exc:
        sys.stderr.write('file open failed: %s' % (exc[-1]))
        return

    # otherwise show a diagnostic 'ok'
    else:
        sys.stderr.write('file opened successfully\n')

    # read all data and close file
    txns = ccfile.readlines()
    ccfile.close()

    # processing setup
    total = 0.00
    sys.stderr.write('processing new account, log:\n')

    # look at each transaction
    for eachTxn in txns:
        result = safe_float(eachTxn)

        # string indicates failure ...
        if type(result) == types.StringType:
            if eachTxn[0] == '#':
                sys.stderr.write('comment... ignored\n')
            else:
                sys.stderr.write('\ncategory: %s' % eachTxn)

        # ... while float means success
        elif type(result) == types.FloatType:
            total = total + result
            sys.stderr.write('processing transaction of: %.2f\n' % result)

        # unknown return type from safe_float()
        else:
            sys.stderr.write('invalid return type from safe_float()... ignored\n')

    # display final totals
    print 'new balance: $%.2f' % (total)


# call main() if invoked as script
if __name__ == '__main__':
    main()
