Exercise 5.3 - Solution

(a) Better output for printing objects

# stock.py

class Stock(object):
    '''
    An instance of a stock holding consisting of name, shares, and price.
    '''
    def __init__(self, name, shares, price):
        self.name   = name
        self.shares = shares
        self.price  = price

    def __repr__(self):
        return 'Stock(%r, %r, %r)' % (self.name, self.shares, self.price)

    def cost(self):
        '''
        Return the cost as shares*price
        '''
        return self.shares * self.price

    def sell(self, nshares):
        '''
        Sell a number of shares and return the remaining number.
        '''
        self.shares -= nshares
        return self.shares
...

(b) Defining a custom exception

# tableformat.py
...

class FormatError(Exception):
    pass

def create_formatter(name):
    '''
    Create an appropriate formatter given an output format name
    '''
    if name == 'txt':
        return TextTableFormatter()
    elif name == 'csv':
        return CSVTableFormatter()
    elif name == 'html':
        return HTMLTableFormatter()
    else:
        raise FormatError('Unknown table format %s' % name)

(c) An example of using getattr()

# tableformat.py

...
def print_table(objects, columns, formatter):
    '''
    Make a nicely formatted table from a list of objects and attribute names.
    '''
    formatter.headings(columns)
    for obj in objects:
        rowdata = [ str(getattr(obj, name)) for name in columns ]
        formatter.row(rowdata)

(d) Column Formatting

# tableformat.py

...
def print_table(objects, columns, formats, formatter):
    '''
    Make a nicely formatted table from a list of objects and attribute names.
    '''
    formatter.headings(columns)
    for obj in objects:
        rowdata = [ (fmt % getattr(obj, name))
                    for name,fmt in zip(columns, formats) ]
        formatter.row(rowdata)

[ Back ]