Skip to content

Commit 70e10d3

Browse files
committed
end of 3.4
1 parent 97f2b92 commit 70e10d3

6 files changed

Lines changed: 112 additions & 95 deletions

File tree

Work/Data/missing.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name,shares,price
22
"AA",100,32.20
33
"IBM",,91.10
4+
45
"CAT",150,83.44
56
"MSFT",,51.23
67
"GE",95,40.37

Work/fileparse.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
# Exercise 3.3
44
import csv
55

6-
def parse_csv(filename, select=None, types=None, has_headers=True, delimiter=','):
6+
def parse_csv(filename, select=None, types=None, has_headers=True, delimiter=',', silence_errors=True):
77
'''
88
Parse a CSV file into a list of records
99
'''
10+
if select and not has_headers:
11+
raise RuntimeError("select argument requires column headers")
12+
1013
with open(filename) as f:
1114
rows = csv.reader(f, delimiter=delimiter)
1215

1316
# Read the file headers
1417
if has_headers:
1518
headers = next(rows)
19+
start = 2
20+
else:
21+
headers = []
22+
start = 1
1623

1724
# If a column selector was given, find indices of the specified columns.
1825
# Also narrow the set of headers used for resulting dictionaries
@@ -23,18 +30,25 @@ def parse_csv(filename, select=None, types=None, has_headers=True, delimiter=','
2330
indices = []
2431

2532
records = []
26-
for row in rows:
33+
for rownum, row in enumerate(rows, start=start):
2734
if not row: # Skip rows with no data
2835
continue
36+
try:
37+
# Filter the row if specific columns were selected
38+
if indices:
39+
row = [ row[index] for index in indices ]
40+
41+
# Convert types if a list of types is provided
42+
if types:
43+
row = [func(val) for func, val in zip(types, row) ]
44+
45+
except ValueError as e:
46+
if not silence_errors:
47+
print(f"Row {rownum}: Could not convert: {row}")
48+
print(f"Row {rownum}: Reason: {e}\n")
49+
continue
2950

30-
# Filter the row if specific columns were selected
31-
if indices:
32-
row = [ row[index] for index in indices ]
33-
34-
# Convert types if a list of types is provided
35-
if types:
36-
row = [func(val) for func, val in zip(types, row) ]
37-
# print(row)
51+
# print(list(zip(headers, row)))
3852
if has_headers:
3953
record = dict(zip(headers, row))
4054
else:
@@ -52,7 +66,11 @@ def parse_csv(filename, select=None, types=None, has_headers=True, delimiter=','
5266
# prices = parse_csv('.\\Data\\prices.csv', types=[str,float], has_headers=False)
5367
# print(prices)
5468

55-
portfolio = parse_csv('.\\Data\\portfolio.dat', types=[str, int, float], delimiter=' ')
56-
print(portfolio)
69+
# portfolio = parse_csv('.\\Data\\portfolio.dat', types=[str, int, float], delimiter=' ')
70+
# print(portfolio)
5771

72+
# portfolio = parse_csv('.\\Data\\portfolio.csv', select=['name','shares'], types=[str, int], has_headers=False)
73+
# print(portfolio)
5874

75+
# portfolio = parse_csv('.\\Data\\missing.csv', types=[str, int, float], silence_errors=False)
76+
# print(portfolio)

Work/pcost.3.14.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# Exercise 3.14
3+
4+
from report import read_portfolio
5+
6+
def portfolio_cost(filename):
7+
''' Calculate total cost of portofolio '''
8+
9+
portfolio = read_portfolio(filename)
10+
return sum([i['shares'] * i['price'] for i in portfolio ]) # testing
11+
12+
13+
14+
cost = portfolio_cost('.\\Data\\portfolio.csv') # testing
15+
16+
print(f'Total cost of portfolio: ${cost:0.2f}') # testing
17+

Work/pcost.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# pcost.py
22
#
33
# Exercise 1.27
4+
45
value = 0.0
56

67
with open('.\\Data\\portfolio.csv', 'rt') as f:
@@ -14,3 +15,6 @@
1415
print(f'{row[0].strip('"'):5s} {itemvalue:8.2f} {showvalue:10s}')
1516

1617
print(f'Total cost of portfolio: ${value:0.2f}')
18+
19+
20+

Work/report.py

Lines changed: 45 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,59 @@
33
# Exercise 2.4 - 2.12
44
import csv
55
from pprint import pprint
6+
from fileparse import parse_csv
7+
8+
69

710
def read_prices(filename):
811
"""Reads stock prices from a CSV file and returns a dictionary mapping stock names to prices."""
9-
prices = {}
10-
with open(filename, 'rt') as f:
11-
rows = csv.reader(f)
12+
# prices = {}
13+
# with open(filename, 'rt') as f:
14+
# rows = csv.reader(f)
1215

13-
for row in rows:
14-
if not row: # Skip empty rows
15-
continue
16+
# for row in rows:
17+
# if not row: # Skip empty rows
18+
# continue
1619

17-
prices[row[0]] = float(row[1])
20+
# prices[row[0]] = float(row[1])
21+
prices = parse_csv(filename, types=[str,float], has_headers=False)
1822

19-
return prices
23+
return dict(prices)
2024

2125
def read_portfolio(filename):
2226
"""Reads a stock portfolio from a CSV file with handling for missing files."""
23-
value = 0.0
24-
data_list = []
27+
# value = 0.0
28+
# data_list = []
2529

26-
try:
27-
28-
with open(filename, 'rt') as f:
29-
rows = csv.reader(f)
30-
headers = next(rows) # skip the header line
31-
32-
for rownum, row in enumerate(rows, start=2):
33-
# data_dict = {
34-
# 'name': row[0],
35-
# 'shares': int(row[1]),
36-
# 'price': float(row[2])
37-
# }
38-
record = dict(zip(headers, row))
39-
try:
40-
record['shares'] = int(record['shares'])
41-
record['price'] = float(record['price'])
42-
# value += num_shares * price
43-
data_list.append(record)
44-
45-
except ValueError:
46-
print(f'Line {rownum}: Bad line: {row}')
30+
# try:
31+
32+
# with open(filename, 'rt') as f:
33+
# rows = csv.reader(f)
34+
# headers = next(rows) # skip the header line
35+
36+
# for rownum, row in enumerate(rows, start=2):
37+
# # data_dict = {
38+
# # 'name': row[0],
39+
# # 'shares': int(row[1]),
40+
# # 'price': float(row[2])
41+
# # }
42+
# record = dict(zip(headers, row))
43+
# try:
44+
# record['shares'] = int(record['shares'])
45+
# record['price'] = float(record['price'])
46+
# # value += num_shares * price
47+
# data_list.append(record)
48+
49+
# except ValueError:
50+
# print(f'Line {rownum}: Bad line: {row}')
4751

48-
return data_list, headers
52+
# return data_list, headers
4953

50-
except FileNotFoundError:
51-
print(f'Error: The file {filename} was not found.')
52-
return None
54+
# except FileNotFoundError:
55+
# print(f'Error: The file {filename} was not found.')
56+
# return None
57+
portfolio = parse_csv(filename, types=[str, int, float])
58+
return portfolio
5359

5460
def make_report(portfolio, prices):
5561
"""Generates a report of the portfolio with current prices and gain/loss."""
@@ -73,65 +79,21 @@ def print_report(report):
7379

7480
def portfolio_report(portfolio_file, prices_file):
7581
"""Generates and prints a portfolio report from given files."""
82+
7683
curr_prices = read_prices(prices_file)
77-
portfolio_data = read_portfolio(portfolio_file)
84+
portfolio = read_portfolio(portfolio_file)
7885

79-
if portfolio_data is None:
86+
if portfolio is None:
8087
return # Exit if portfolio file was not found
8188

82-
portfolio, headers = portfolio_data
8389
report = make_report(portfolio, curr_prices)
8490
print_report(report)
8591

8692
# portfolio_report('.\\Data\\portfoliodate.csv', '.\\Data\\prices.csv')
8793

88-
files = ['.\\Data\\portfolio.csv', '.\\Data\\portfolio2.csv']
89-
for file in files:
90-
print(f'{file:-^43s}')
91-
portfolio_report(file, '.\\Data\\prices.csv')
92-
print()
94+
9395

9496
# curr_prices = read_prices('.\\Data\\prices.csv')
9597
# portfolio_data = read_portfolio('.\\Data\\portfoliodate.csv')
9698
# report = make_report(portfolio_data[0], curr_prices)
9799
# print_report(report)
98-
99-
100-
101-
'''
102-
pf_data = portfolio[0]
103-
headers = portfolio[1]
104-
105-
for h in headers:
106-
print('%10s' % h, end=' ')
107-
print()
108-
print(('-' * 10 + ' ') * len(headers))
109-
110-
# for r in report:
111-
# print('%10s %10d %10.2f %10.2f' % r)
112-
113-
# for name, shares, price, change in report:
114-
# dollar_price = f'${price:0.2f}'
115-
# print(f'{name:>10s} {shares:>10d} {dollar_price:>10s} {change:>10.2f}')
116-
117-
for row in pf_data:
118-
# for i,j in row.items():
119-
# print(f'{j:>10s}', end=' ')
120-
# print()
121-
for i in list(row.values()):
122-
print(f'{i:>10}', end=' ')
123-
print()
124-
'''
125-
126-
127-
128-
129-
130-
131-
132-
133-
134-
135-
136-
137-

Work/using_report.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import report as r
2+
3+
# pf_files = ['.\\Data\\portfolio.csv', '.\\Data\\portfolio2.csv']
4+
price_file = '.\\Data\\prices.csv'
5+
6+
# for file in pf_files:
7+
# print(f'{file:-^43s}')
8+
# r.portfolio_report(file, price_file)
9+
# print()
10+
11+
pf_file = '.\\Data\\portfolio.csv'
12+
13+
print(f'{pf_file:-^43s}')
14+
r.portfolio_report(pf_file, price_file)
15+
print()

0 commit comments

Comments
 (0)