Visitar URL original
complete section 6.3 · dabeaz-course/practical-python@0f55037 · GitHub
Skip to content

Commit 0f55037

Browse files
author
iram lee
committed
complete section 6.3
1 parent 50ed033 commit 0f55037

6 files changed

Lines changed: 148 additions & 22 deletions

File tree

‎Work/follow.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# follow.py
2+
import os
3+
import time
4+
5+
6+
def follow(filename):
7+
f = open(filename)
8+
f.seek(0, os.SEEK_END) # Move file pointer 0 bytes from end of file
9+
while True:
10+
line = f.readline()
11+
if line:
12+
yield line
13+
14+
15+
if __name__ == '__main__':
16+
import report
17+
18+
portfolio = report.read_portfolio('Data/portfolio.csv')
19+
20+
for line in follow('Data/stocklog.csv'):
21+
fields = line.split(',')
22+
name = fields[0].strip('"')
23+
price = float(fields[1])
24+
change = float(fields[4])
25+
if name in portfolio:
26+
print(f'{name:>10s} {price:>10.2f} {change:>10.2f}')
27+

‎Work/pcost.py‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,22 @@
77
import report
88

99
def portfolio_cost(filename):
10-
total_cost = 0.0
11-
stock_price = 0.0
12-
num_of_shares = 0
13-
records = report.read_portfolio(filename)
10+
# total_cost = 0.0
11+
# stock_price = 0.0
12+
# num_of_shares = 0
13+
portfolio = report.read_portfolio(filename)
1414

15-
for lineno, record in enumerate(records, start=1):
16-
try:
17-
nshares = int(record.shares)
18-
price = float(record.price)
19-
total_cost += nshares * price
20-
# This catches errors in int() and float() conversions above
21-
except ValueError:
22-
print(f'Row {lineno}: Bad row: {line}')
15+
# for lineno, record in enumerate(records, start=1):
16+
# try:
17+
# nshares = int(record.shares)
18+
# price = float(record.price)
19+
# total_cost += nshares * price
20+
# # This catches errors in int() and float() conversions above
21+
# except ValueError:
22+
# print(f'Row {lineno}: Bad row: {line}')
2323

24-
return total_cost
24+
return portfolio.total_cost
25+
2526

2627
def main(argv):
2728
if len(argv) == 2:

‎Work/portfolio.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# portfolio.py
2+
3+
class Portfolio:
4+
5+
def __init__(self, holdings):
6+
self._holdings = holdings
7+
8+
9+
def __iter__(self):
10+
return self._holdings.__iter__()
11+
12+
13+
def __len__(self):
14+
return len(self._holdings)
15+
16+
17+
def __getitem__(self, index):
18+
return self._holdings[index]
19+
20+
21+
def __contains__(self, name):
22+
return any([s.name == name for s in self._holdings])
23+
24+
25+
@property
26+
def total_cost(self):
27+
return sum([s.cost for s in self._holdings])
28+
29+
30+
def tabulate_shares(self):
31+
from collections import Counter
32+
total_shares = Counter()
33+
for s in self._holdings:
34+
total_shares[s.name] += s.shares
35+
return total_shares

‎Work/report.py‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import fileparse
88
import stock
99
import tableformat
10+
from portfolio import Portfolio
1011

1112
def read_portfolio(filename):
1213
with open(filename) as f:
1314
portdicts = fileparse.parse_csv(f, select=['name', 'shares', 'price'], types=[str, int, float])
1415
portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts ]
15-
return portfolio
16+
return Portfolio(portfolio)
1617

1718

1819
def read_prices(filename):
@@ -35,17 +36,9 @@ def make_report(portfolio, prices):
3536

3637
def print_report(reportdata, formatter):
3738
formatter.headings(['Name','Shares','Price','Change'])
38-
# headers = ('Name', 'Shares', 'Price', 'Change')
39-
# separator = '----------'
40-
# print(f'{headers[0]:>10s} {headers[1]:>10s} {headers[2]:>10s} {headers[3]:>10s}')
41-
# print(f'{separator:>10s} {separator:>10s} {separator:>10s} {separator:>10s}')
4239
for name, shares, price, change in reportdata:
4340
rowdata = [ name, str(shares), f'{price:0.2f}', f'{change:0.2f}']
4441
formatter.row(rowdata)
45-
# currency_sym = '$'
46-
# for name, shares, price, change in report:
47-
# money = f'{currency_sym}{price:0.2f}'
48-
# print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')
4942

5043

5144
def portfolio_report(portfolio_filename, prices_filename, fmt='txt'):

‎Work/stock.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
class Stock:
22

3+
__slots__ = 'name', '_shares', 'price'
4+
35
def __init__(self, name, shares, price):
46
self.name = name
57
self.shares = shares
@@ -9,10 +11,23 @@ def __init__(self, name, shares, price):
911
def __repr__(self):
1012
return f'Stock({self.name}, {self.shares}, {self.price})'
1113

14+
15+
@property
16+
def shares(self):
17+
return self._shares
18+
19+
20+
@shares.setter
21+
def shares(self, value):
22+
if not isinstance(value, int):
23+
raise TypeError('Expected int')
24+
self._shares = value
25+
1226

1327
def sell(self, qty):
1428
self.shares -= qty
1529

1630

31+
@property
1732
def cost(self):
1833
return self.shares * self.price

‎Work/ticker.py‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# ticker.py
2+
3+
from follow import follow
4+
import csv
5+
import report
6+
import tableformat
7+
8+
def select_columns(rows, indices):
9+
for row in rows:
10+
yield [ row[index] for index in indices ]
11+
12+
13+
def convert_types(rows, types):
14+
for row in rows:
15+
yield [func(val) for func, val in zip(types, row)]
16+
17+
18+
def make_dicts(rows, headers):
19+
for row in rows:
20+
yield dict(zip(headers, row))
21+
22+
23+
def filter_symbols(rows, names):
24+
for row in rows:
25+
if row['name'] in names:
26+
yield row
27+
28+
29+
def parse_stock_data(lines):
30+
rows = csv.reader(lines)
31+
rows = select_columns(rows, [0, 1, 4])
32+
rows = convert_types(rows, [str, float, float])
33+
rows = make_dicts(rows, ['name', 'price', 'change'])
34+
return rows
35+
36+
37+
def ticker(portfile, logfile, fmt):
38+
portfolio = report.read_portfolio(portfile)
39+
lines = follow(logfile)
40+
rows = parse_stock_data(lines)
41+
rows = filter_symbols(rows, portfolio)
42+
formatter = tableformat.create_formatter(fmt)
43+
formatter.headings(['Name', 'Price', 'Change'])
44+
for row in rows:
45+
formatter.row([ row['name'], f"{row['price']:0.2f}", f"{row['change']:0.2f}"])
46+
47+
48+
49+
if __name__ == '__main__':
50+
51+
portfolio = report.read_portfolio('Data/portfolio.csv')
52+
rows = parse_stock_data(follow('Data/stocklog.csv'))
53+
rows = filter_symbols(rows, portfolio)
54+
for row in rows:
55+
print(row)

0 commit comments

Comments
 (0)