--- id: practical-python-4.6 source_exercise_id: "4.6" title: "Using Inheritance to Produce Different Output" section: "4.2 Inheritance" source_path: "04_Classes_objects/02_Inheritance.md" source_repo: "https://github.com/dabeaz-course/practical-python" source_commit: "93dca856b41c61a0a0f85ae334116e4c125629ea" student_visible_solution: false has_private_solution: false skip: false --- # Exercise 4.6: Using Inheritance to Produce Different Output > Source: Practical Python Programming, `04_Classes_objects/02_Inheritance.md`. ### Exercise 4.6: Using Inheritance to Produce Different Output The `TableFormatter` class you defined in part (a) is meant to be extended via inheritance. In fact, that's the whole idea. To illustrate, define a class `TextTableFormatter` like this: ```python # tableformat.py ... class TextTableFormatter(TableFormatter): ''' Emit a table in plain-text format ''' def headings(self, headers): for h in headers: print(f'{h:>10s}', end=' ') print() print(('-'*10 + ' ')*len(headers)) def row(self, rowdata): for d in rowdata: print(f'{d:>10s}', end=' ') print() ``` Modify the `portfolio_report()` function like this and try it: ```python # report.py ... 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 formatter = tableformat.TextTableFormatter() print_report(report, formatter) ``` This should produce the same output as before: ```python >>> ================================ RESTART ================================ >>> import report >>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv') Name Shares Price Change ---------- ---------- ---------- ---------- AA 100 9.22 -22.98 IBM 50 106.28 15.18 CAT 150 35.46 -47.98 MSFT 200 20.89 -30.34 GE 95 13.48 -26.89 MSFT 50 20.89 -44.21 IBM 100 106.28 35.84 >>> ``` However, let's change the output to something else. Define a new class `CSVTableFormatter` that produces output in CSV format: ```python # tableformat.py ... class CSVTableFormatter(TableFormatter): ''' Output portfolio data in CSV format. ''' def headings(self, headers): print(','.join(headers)) def row(self, rowdata): print(','.join(rowdata)) ``` Modify your main program as follows: ```python 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 formatter = tableformat.CSVTableFormatter() print_report(report, formatter) ``` You should now see CSV output like this: ```python >>> ================================ RESTART ================================ >>> import report >>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv') Name,Shares,Price,Change AA,100,9.22,-22.98 IBM,50,106.28,15.18 CAT,150,35.46,-47.98 MSFT,200,20.89,-30.34 GE,95,13.48,-26.89 MSFT,50,20.89,-44.21 IBM,100,106.28,35.84 ``` Using a similar idea, define a class `HTMLTableFormatter` that produces a table with the following output: ``` NameSharesPriceChange AA1009.22-22.98 IBM50106.2815.18 CAT15035.46-47.98 MSFT20020.89-30.34 GE9513.48-26.89 MSFT5020.89-44.21 IBM100106.2835.84 ``` Test your code by modifying the main program to create a `HTMLTableFormatter` object instead of a `CSVTableFormatter` object. ## 关联来源 - [[summaries/02_Inheritance]]