Added solution code

This commit is contained in:
David Beazley
2020-05-27 17:03:35 -05:00
parent 960d4fa2fa
commit 5b6f15db17
136 changed files with 5828 additions and 350 deletions

View File

@@ -0,0 +1,47 @@
# fileparse.py
import csv
def parse_csv(lines, select=None, types=None, has_headers=True, delimiter=',', silence_errors=False):
'''
Parse a CSV file into a list of records with type conversion.
'''
if select and not has_headers:
raise RuntimeError('select requires column headers')
rows = csv.reader(lines, delimiter=delimiter)
# Read the file headers (if any)
headers = next(rows) if has_headers else []
# If specific columns have been selected, make indices for filtering and set output columns
if select:
indices = [ headers.index(colname) for colname in select ]
headers = select
records = []
for rowno, row in enumerate(rows, 1):
if not row: # Skip rows with no data
continue
# If specific column indices are selected, pick them out
if select:
row = [ row[index] for index in indices]
# Apply type conversion to the row
if types:
try:
row = [func(val) for func, val in zip(types, row)]
except ValueError as e:
if not silence_errors:
print(f"Row {rowno}: Couldn't convert {row}")
print(f"Row {rowno}: Reason {e}")
continue
# Make a dictionary or a tuple
if headers:
record = dict(zip(headers, row))
else:
record = tuple(row)
records.append(record)
return records

20
Solutions/4_4/pcost.py Normal file
View File

@@ -0,0 +1,20 @@
# pcost.py
import report
def portfolio_cost(filename):
'''
Computes the total cost (shares*price) of a portfolio file
'''
portfolio = report.read_portfolio(filename)
return sum([s.cost() for s in portfolio])
def main(args):
if len(args) != 2:
raise SystemExit('Usage: %s portfoliofile' % args[0])
filename = args[1]
print('Total cost:', portfolio_cost(filename))
if __name__ == '__main__':
import sys
main(sys.argv)

70
Solutions/4_4/report.py Normal file
View File

@@ -0,0 +1,70 @@
# report.py
import fileparse
from stock import Stock
def read_portfolio(filename):
'''
Read a stock portfolio file into a list of dictionaries with keys
name, shares, and price.
'''
with open(filename) as lines:
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float])
portfolio = [ Stock(d['name'], d['shares'], d['price']) for d in portdicts ]
return portfolio
def read_prices(filename):
'''
Read a CSV file of price data into a dict mapping names to prices.
'''
with open(filename) as lines:
return dict(fileparse.parse_csv(lines, types=[str,float], has_headers=False))
def make_report_data(portfolio, prices):
'''
Make a list of (name, shares, price, change) tuples given a portfolio list
and prices dictionary.
'''
rows = []
for s in portfolio:
current_price = prices[s.name]
change = current_price - s.price
summary = (s.name, s.shares, current_price, change)
rows.append(summary)
return rows
def print_report(reportdata):
'''
Print a nicely formated table from a list of (name, shares, price, change) tuples.
'''
headers = ('Name','Shares','Price','Change')
print('%10s %10s %10s %10s' % headers)
print(('-'*10 + ' ')*len(headers))
for row in reportdata:
print('%10s %10d %10.2f %10.2f' % row)
def portfolio_report(portfoliofile, pricefile):
'''
Make a stock report given portfolio and price data files.
'''
# Read data files
portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile)
# Create the report data
report = make_report_data(portfolio, prices)
# Print it out
print_report(report)
def main(args):
if len(args) != 3:
raise SystemExit('Usage: %s portfile pricefile' % args[0])
portfolio_report(args[1], args[2])
if __name__ == '__main__':
import sys
main(sys.argv)

23
Solutions/4_4/stock.py Normal file
View File

@@ -0,0 +1,23 @@
# 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 cost(self):
'''
Return the cost as shares*price
'''
return self.shares * self.price
def sell(self, nshares):
'''
Sell a number of shares
'''
self.shares -= nshares