Exercise 2.4 - Solution

(d) Using the zip() function

# report.py
import csv

def read_portfolio(filename):
    '''
    Read a stock portfolio file into a list of dictionaries with keys
    name, shares, and price.
    '''
    portfolio = []
    f = open(filename)
    f_csv = csv.reader(f)
    headers = next(f_csv)

    for row in f_csv:
        record = dict(zip(headers, row))
        stock = {
            'name' : record['name'],
            'shares' : int(record['shares']),
            'price' : float(record['price'])
        }
        portfolio.append(stock)
    f.close()
    return portfolio

def read_prices(filename):
    '''
    Read a CSV file of price data into a dict mapping names to prices.
    '''
    prices = {}
    f = open(filename)
    f_csv = csv.reader(f)
    for row in f_csv:
        try:
            prices[row[0]] = float(row[1])
        except IndexError:
            pass
    f.close()
    return prices

def make_report(portfolio, prices):
    '''
    Make a list of (name, shares, price, change) tuples given a portfolio list
    and prices dictionary.
    '''
    rows = []
    for stock in portfolio:
        current_price = prices[stock['name']]
        change        = current_price - stock['price']
        summary       = (stock['name'], stock['shares'], current_price, change)
        rows.append(summary)
    return rows

# Read data files and create the report data

portfolio = read_portfolio('../../Data/portfoliodate.csv')
prices    = read_prices('../../Data/prices.csv')

# Generate the report data

report    = make_report(portfolio, prices)

# Output the report
headers = ('Name', 'Shares', 'Price', 'Change')
print ('%10s ' * len(headers)) % headers
print ('-' * 10 + ' ') * len(headers)
for row in report:
    print '%10s %10d %10.2f %10.2f' % row

[ Back ]