@@ -148,6 +148,125 @@ def portfolio_report(portfolio_filename, prices_filename):
148148portfolio_report (file_portfolio , file_price )
149149
150150
151+ # report.py
152+ #
153+ # Exercise 2.4
154+ import csv
155+ from pprint import pprint
156+ from fileparse_copy import parse_csv
157+
158+ def portfolio_cost (filename ):
159+ '''
160+ Computes the total cost (shares*price) of a portfolio file
161+ '''
162+ total_cost = 0.0
163+
164+ with open (filename , 'rt' ) as f :
165+ rows = csv .reader (f )
166+ headers = next (rows )
167+ for rowno , row in enumerate (rows ):
168+ record = dict (zip (headers , row ))
169+ try :
170+ nshares = int (record ['shares' ])
171+ price = float (record ['price' ])
172+ total_cost += nshares * price
173+ except ValueError :
174+ print (f"Row { row_no } : Bad row: { row } " )
175+ return total_cost
176+
177+
178+ def read_portfolio (filename , select = ['name' ,'shares' ,'price' ], types = [str ,int ,float ], has_headers = True ):
179+ '''
180+ Opens a given portfolio file and reads it into a list of dictionaries
181+ '''
182+ portfolio = parse_csv (filename , select = select , types = types , has_headers = has_headers )
183+
184+ return portfolio
185+
186+
187+ def read_prices (filename , types = [str , float ], has_headers = False ): #, select=None, types=None, has_headers=True, delimiter=',', silence_errors=False):
188+ '''
189+ Reads a set of prices into a dictionary where the keys of the
190+ dictionary are the stock names and the values in the dictionary are the stock prices
191+ '''
192+ list_prices = parse_csv (filename , types = types , has_headers = has_headers ) #, select, types, has_headers, delimiter, silence_errors)
193+ prices = dict (list_prices )
194+
195+ return prices
196+
197+
198+ def current_value (portfolio , prices ):
199+ '''
200+ Computes current value of portfolio
201+ '''
202+ current_value = 0.0
203+
204+ for i in portfolio :
205+ current_value += i ['shares' ] * prices [i ['name' ]]
206+
207+ return current_value
208+
209+
210+ def make_report (portfolio , prices ):
211+ '''
212+ Takes a list of stocks and dictionary of prices as input and
213+ returns a list of tuples containing the rows of the above table
214+ '''
215+
216+ report = [] # list of tuples
217+
218+ for stock in portfolio :
219+ name = stock ['name' ]
220+ shares = stock ['shares' ]
221+ price = prices [name ]
222+ change = price - stock ['price' ]
223+ t = (name , shares , price , change )
224+ report .append (t )
225+
226+ return report
227+
228+
229+ def print_report (report ):
230+ '''
231+ Prints out report
232+ '''
233+ headers = ('Name' , 'Shares' , 'Price' , 'Change' )
234+ print (f'{ headers [0 ]:>10s} { headers [1 ]:>10s} { headers [2 ]:>10s} { headers [3 ]:>10s} ' )
235+ seperator = '---------- ---------- ---------- ----------'
236+ print (seperator )
237+ # print formatted report
238+ for name , shares , price , change in report :
239+ if price :
240+ price = '$' + str (price )
241+ print (f'{ name :>10s} { shares :>10d} { price :>10s} { change :>10.2f} ' )
242+
243+
244+ def portfolio_report (portfolio_filename , prices_filename ):
245+ '''
246+ Makes and prints out final report
247+ '''
248+ portfolio = read_portfolio (portfolio_filename )
249+ prices = read_prices (prices_filename )
250+ report = make_report (portfolio , prices )
251+
252+ return (print_report (report ))
253+
254+
255+ # file paths
256+ file_portfolio = 'Data/portfolio.csv'
257+ file_price = 'Data/prices.csv'
258+
259+ # call functions
260+ portfolio_report (file_portfolio , file_price )
261+
262+
263+
264+
265+
266+
267+
268+
269+
151270
152271
153272
0 commit comments