Skip to content

Commit 453e157

Browse files
committed
end of 2 Working with data
1 parent 20060dc commit 453e157

8 files changed

Lines changed: 263 additions & 28 deletions

File tree

Work/.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"workbench.editor.autoLockGroups": {
3+
"terminalEditor": false
4+
}
5+
}

Work/Data/missing.csv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name,shares,price
2+
"AA",100,32.20
3+
"IBM",,91.10
4+
"CAT",150,83.44
5+
"MSFT",,51.23
6+
"GE",95,40.37
7+
"MSFT",50,65.10
8+
"IBM",100,70.44

Work/exercise.2.26.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import csv
2+
3+
f = open('.\\Data\\dowstocks.csv')
4+
rows = csv.reader(f)
5+
headers = next(rows) # ['name', 'price', 'date', 'time', 'change', 'open', 'high', 'low', 'volume']
6+
# row = next(rows) # ['AA', '39.48', '6/11/2007', '9:36am', '-0.18', '39.67', '39.69', '39.45', '181800']
7+
8+
types = [str, float, str, str, float, float, float, float, int]
9+
10+
# record = { name: func(val) for name, func, val in zip(headers, types, row) }
11+
# print(record)
12+
# {'name': 'AA', 'price': 39.48, 'date': '6/11/2007', 'time': '9:36am', 'change': -0.18, 'open': 39.67, 'high': 39.69, 'low': 39.45, 'volume': 181800}
13+
14+
records = [ { name: func(val) for name, func, val in zip(headers, types, row) } for row in rows]
15+
print(records[:3])
16+
# [{'name': 'IBM', 'price': 91.10, 'date': '5/13/2007', 'time': '4:20pm', 'change': 0.56, 'open': 90.54, 'high': 91.20, 'low': 90.50, 'volume': 183900}, {'name': 'CAT', 'price': 83.44, 'date': '9/23/2006', 'time': '1:30pm', 'change': -0.12, 'open': 83.56, 'high': 83.80, 'low': 83.40, 'volume': 121500}, {'name': 'MSFT', 'price': 51.23, 'date': '5/17/2007', 'time': '10:30am', 'change': 0.15, 'open': 51.08, 'high': 51.30, 'low': 51.00, 'volume': 195500}]
17+
18+
19+
for record in records[:3]:
20+
for name, val in record.items():
21+
if name == 'date':
22+
record[name] = tuple(val.split('/'))
23+
24+
25+
26+
print(records[:3])
27+
28+
29+
30+
31+

Work/exercise2.23.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# extracting data from csv file
2+
'''
3+
name,date,time,shares,price
4+
"AA","6/11/2007","9:50am",100,32.20
5+
"IBM","5/13/2007","4:20pm",50,91.10
6+
"CAT","9/23/2006","1:30pm",150,83.44
7+
"MSFT","5/17/2007","10:30am",200,51.23
8+
"GE","2/1/2006","10:45am",95,40.37
9+
"MSFT","10/31/2006","12:05pm",50,65.10
10+
"IBM","7/9/2006","3:15pm",100,70.44
11+
'''
12+
import csv
13+
14+
f = open('.\\Data\\portfoliodate.csv')
15+
rows = csv.reader(f)
16+
headers = next(rows)
17+
print(headers)
18+
# ['name', 'date', 'time', 'shares', 'price']
19+
20+
selected_rows = ['name', 'shares', 'price']
21+
22+
indices = [headers.index(colname) for colname in selected_rows]
23+
print(indices)
24+
# [0, 3, 4]
25+
26+
# editor.inlineSuggest.enabled set it false, then again true 31.1.2026
27+
28+
row = next(rows)
29+
# turn a row into a dictionary
30+
# zip(selected_rows, indices) -> ('name', 0), ('shares', 3), ('price', 4)
31+
record = { colname: row[index] for colname, index in zip(selected_rows, indices)}
32+
# {'name': 'AA', 'shares': '100', 'price': '32.20'}
33+
34+
portfolio = [ { colname: row[index] for colname, index in zip(selected_rows, indices)} for row in rows]
35+
print(portfolio)
36+
37+
# [{'name': 'IBM', 'shares': '50', 'price': '91.10'}, {'name': ... ]

Work/exercise2.24.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import csv
2+
3+
types = [str, int, float]
4+
5+
f = open('.\\Data\\portfolio.csv')
6+
rows = csv.reader(f)
7+
headers = next(rows)
8+
row = next(rows)
9+
print(row)
10+
11+
print(types[1](row[1])*types[2](row[2]))
12+
13+
r = list(zip(types, row))
14+
# [(<class 'str'>, 'AA'), (<class 'int'>, '100'), (<class 'float'>, '32.20')]
15+
16+
converted = [func(val) for func, val in zip(types, row)] # [str('AA'), int('100'), float('32.20')]
17+
print(converted,'\t' , converted[1] * converted[2])
18+
# ['AA', 100, 32.2] 3220.0000000000005
19+
20+
21+
# { name: func(val) for name, func, val in zip(headers, types, row) }
22+
23+
print(list(zip(headers, types, row))) # [('name', <class 'str'>, 'AA'), ('shares', ... ]
24+
25+
record = { name: func(val) for name, func, val in zip(headers, types, row) }
26+
print(record) # {'name': 'AA', 'shares': 100, 'price': 32.2}
27+

Work/exercise2.5.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
from collections import Counter
3+
4+
portfolio = [
5+
('GOOG', 100, 490.1),
6+
('IBM', 50, 91.1),
7+
('CAT', 150, 83.44),
8+
('IBM', 100, 45.23),
9+
('GOOG', 75, 572.45),
10+
('AA', 50, 23.15)
11+
]
12+
13+
# combine the shares for each stock
14+
total_shares = Counter()
15+
for name, shares, price in portfolio:
16+
total_shares[name] += shares
17+
18+
print(total_shares)
19+
20+
# map each stock to a list of (shares, price) tuples
21+
from collections import defaultdict
22+
23+
holdings = defaultdict(list)
24+
for name, shares, price in portfolio:
25+
holdings[name].append((shares, price))
26+
27+
print(holdings)
28+
29+
30+
31+
# https://www.geeksforgeeks.org/python/deque-in-python/
32+
# https://docs.python.org/3/library/collections.html#collections.deque
33+
from collections import deque
34+
35+
filename = '.\\Data\\portfolio.csv'
36+
history = deque(maxlen=3)
37+
38+
with open(filename) as f:
39+
for line in f:
40+
print(line, end='') # show the line
41+
history.append(line)
42+
43+
print('Last 3 lines:')
44+
for line in history:
45+
print(line, end='')
46+
47+
pf = [{'name': 'AA', 'shares': '100', 'price': '32.20'}, {'name': 'IBM', 'shares': '50', 'price': '91.10'}, {'name': 'CAT', 'shares': '150', 'price': '83.44'}, {'name': 'MSFT', 'shares': '200', 'price': '51.23'}, {'name': 'GE', 'shares': '95', 'price': '40.37'}, {'name': 'MSFT', 'shares': '50', 'price': '65.10'}, {'name': 'IBM', 'shares': '100', 'price': '70.44'}]
48+
49+
holdings = Counter()
50+
51+
for stock in pf:
52+
holdings[stock['name']] += int(stock['shares'])
53+
54+
print(holdings)

Work/pcost.2.15.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# pcost.py
2+
#
3+
# Exercise 2.15
4+
#
5+
import csv
6+
7+
def portfolio_cost(filename):
8+
"""Calculates the total cost of a stock portfolio from a CSV file with handling for missing files."""
9+
value = 0.0
10+
data_list = []
11+
12+
with open(filename, 'rt') as f:
13+
rows = csv.reader(f)
14+
headers = next(rows) # take headers from first line
15+
16+
for linenum, line in enumerate(rows, start=2):
17+
record = dict(zip(headers, line))
18+
# print(record)
19+
try:
20+
num_shares = int(record['shares'])
21+
price = float(record['price'])
22+
value += num_shares * price
23+
data_list.append(record)
24+
except ValueError:
25+
# print(f'Line {linenum}: Bad line: {line.strip()}')
26+
print(f'Line {linenum}: Bad line: {line}')
27+
28+
# return value
29+
return data_list
30+
31+
32+
33+
34+
cost = portfolio_cost('.\\Data\\missing.csv')
35+
# print(f'Total cost of portfolio: ${cost}')
36+
print(cost)
37+

Work/report.py

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# report.py
22
#
3-
# Exercise 2.4
3+
# Exercise 2.4 - 2.12
44
import csv
55
from pprint import pprint
66

@@ -18,53 +18,89 @@ def read_prices(filename):
1818

1919
return prices
2020

21-
2221
def read_portfolio(filename):
2322
"""Reads a stock portfolio from a CSV file with handling for missing files."""
23+
value = 0.0
2424
data_list = []
2525

2626
try:
2727

2828
with open(filename, 'rt') as f:
2929
rows = csv.reader(f)
3030
headers = next(rows) # skip the header line
31-
for row in rows:
32-
data_dict = {
33-
'name': row[0],
34-
'shares': int(row[1]),
35-
'price': float(row[2])
36-
}
37-
data_list.append(data_dict)
38-
return data_list
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}')
47+
48+
return data_list, headers
3949

4050
except FileNotFoundError:
4151
print(f'Error: The file {filename} was not found.')
4252
return None
4353

54+
def make_report(portfolio, prices):
55+
"""Generates a report of the portfolio with current prices and gain/loss."""
56+
report = []
57+
for stock in portfolio:
58+
name = stock['name']
59+
shares = int(stock['shares'])
60+
purchase_price = float(stock['price'])
61+
current_price = prices.get(name, 0.0)
62+
gain_loss = (current_price - purchase_price)
63+
report.append((name, shares, current_price, gain_loss))
64+
return report
65+
66+
4467
curr_prices = read_prices('.\\Data\\prices.csv')
45-
portfolio = read_portfolio('.\\Data\\portfolio.csv')
46-
# portfolio = read_portfolio('.\\Data\\missing.csv')
68+
portfolio = read_portfolio('.\\Data\\portfoliodate.csv')
69+
# print(portfolio[0])
70+
# print(portfolio[1])
71+
pf_data = portfolio[0]
72+
headers = portfolio[1]
73+
74+
report = make_report(pf_data, curr_prices)
75+
76+
for h in headers:
77+
print('%10s' % h, end=' ')
78+
print()
79+
print(('-' * 10 + ' ') * len(headers))
4780

48-
total_cost = 0.0
49-
total_gain_loss = 0.0
50-
curr_value = 0.0
81+
# for r in report:
82+
# print('%10s %10d %10.2f %10.2f' % r)
5183

52-
for s in portfolio: # loop through list of dictionaries
53-
if s['name'] in curr_prices:
54-
print(f"Updating {s['name']} price from {s['price']} to {curr_prices[s['name']]}")
55-
s['current_price'] = curr_prices[s['name']]
56-
s['gain_loss'] = (curr_prices[s['name']] - s['price']) * s['shares']
57-
curr_value += curr_prices[s['name']] * s['shares']
58-
59-
total_gain_loss += s['gain_loss']
60-
total_cost += s['shares'] * s['price']
84+
# for name, shares, price, change in report:
85+
# dollar_price = f'${price:0.2f}'
86+
# print(f'{name:>10s} {shares:>10d} {dollar_price:>10s} {change:>10.2f}')
6187

62-
pprint(portfolio)
88+
for row in pf_data:
89+
# for i,j in row.items():
90+
# print(f'{j:>10s}', end=' ')
91+
# print()
92+
for i in list(row.values()):
93+
print(f'{i:>10}', end=' ')
94+
print()
6395

64-
print(f'Total cost of portfolio: ${total_cost:0.2f} ${total_gain_loss:0.2f} gain/loss Current value: ${curr_value:0.2f}\n')
6596

66-
for s in portfolio:
67-
print(f"{s['name']:6s}: {s['shares']:<6} shares at ${s['price']:0.2f} Current price: ${s['current_price']:<6} Gain/Loss: ${s['gain_loss']:0.2f}")
97+
98+
99+
100+
101+
102+
103+
68104

69105

70106

0 commit comments

Comments
 (0)