In programming, inheritance is a powerful concept that allows us to create new classes based on existing ones. This helps in reusing code and making our programs more extensible. In this part of the experiment, we'll use inheritance to create two new formatters for different output formats: CSV and HTML. These formatters will inherit from a base class, which means they'll share some common behavior while having their own unique ways of formatting data.
Now, let's add the following classes to your tableformat.py file. These classes will define how to format data in CSV and HTML formats respectively.
class CSVTableFormatter(TableFormatter):
"""
Formatter that generates CSV formatted data.
"""
def headings(self, headers):
"""
Generate CSV headers.
"""
print(','.join(headers))
def row(self, rowdata):
"""
Generate a CSV data row.
"""
print(','.join(str(d) for d in rowdata))
class HTMLTableFormatter(TableFormatter):
"""
Formatter that generates HTML table code.
"""
def headings(self, headers):
"""
Generate HTML table headers.
"""
print('<tr>', end=' ')
for header in headers:
print(f'<th>{header}</th>', end=' ')
print('</tr>')
def row(self, rowdata):
"""
Generate an HTML table row.
"""
print('<tr>', end=' ')
for data in rowdata:
print(f'<td>{data}</td>', end=' ')
print('</tr>')
The CSVTableFormatter class is designed to format data in the CSV (Comma-Separated Values) format. The headings method takes a list of headers and prints them separated by commas. The row method takes a list of data for a single row and also prints them separated by commas.
The HTMLTableFormatter class, on the other hand, is used to generate HTML table code. The headings method creates the table headers using HTML <th> tags, and the row method creates a table row using HTML <td> tags.
Let's test these new formatters to see how they work.
- First, let's test the CSV formatter:
import stock
import reader
import tableformat
portfolio = reader.read_csv_as_instances('portfolio.csv', stock.Stock)
formatter = tableformat.CSVTableFormatter()
tableformat.print_table(portfolio, ['name', 'shares', 'price'], formatter)
In this code, we first import the necessary modules. Then we read data from a CSV file named portfolio.csv and create instances of the Stock class. Next, we create an instance of the CSVTableFormatter class. Finally, we use the print_table function to print the portfolio data in CSV format.
You should see the following CSV-formatted output:
name,shares,price
AA,100,32.2
IBM,50,91.1
CAT,150,83.44
MSFT,200,51.23
GE,95,40.37
MSFT,50,65.1
IBM,100,70.44
- Now let's test the HTML formatter:
formatter = tableformat.HTMLTableFormatter()
tableformat.print_table(portfolio, ['name', 'shares', 'price'], formatter)
Here, we create an instance of the HTMLTableFormatter class and use the print_table function again to print the portfolio data in HTML format.
You should see the following HTML-formatted output:
<tr> <th>name</th> <th>shares</th> <th>price</th> </tr>
<tr> <td>AA</td> <td>100</td> <td>32.2</td> </tr>
<tr> <td>IBM</td> <td>50</td> <td>91.1</td> </tr>
<tr> <td>CAT</td> <td>150</td> <td>83.44</td> </tr>
<tr> <td>MSFT</td> <td>200</td> <td>51.23</td> </tr>
<tr> <td>GE</td> <td>95</td> <td>40.37</td> </tr>
<tr> <td>MSFT</td> <td>50</td> <td>65.1</td> </tr>
<tr> <td>IBM</td> <td>100</td> <td>70.44</td> </tr>
As you can see, each formatter produces output in a different format, but they all share the same interface defined by the TableFormatter base class. This is a great example of the power of inheritance and polymorphism. We can write code that works with the base class, and it will automatically work with any subclass.
The print_table() function doesn't need to know anything about the specific formatter being used. It just calls the methods defined in the base class, and the appropriate implementation is selected based on the type of formatter provided. This makes our code more flexible and easier to maintain.