3.2 KiB
id, source_exercise_id, title, section, source_path, source_repo, source_commit, student_visible_solution, has_private_solution, skip
| id | source_exercise_id | title | section | source_path | source_repo | source_commit | student_visible_solution | has_private_solution | skip |
|---|---|---|---|---|---|---|---|---|---|
| practical-python-7.11 | 7.11 | Class Methods in Practice | 7.5 Decorated Methods | 07_Advanced_Topics/05_Decorated_methods.md | https://github.com/dabeaz-course/practical-python | 93dca856b41c61a0a0f85ae334116e4c125629ea | false | true | false |
Exercise 7.11: Class Methods in Practice
Source: Practical Python Programming,
07_Advanced_Topics/05_Decorated_methods.md.
Exercise 7.11: Class Methods in Practice
In your report.py and portfolio.py files, the creation of a Portfolio
object is a bit muddled. For example, the report.py program has code like this:
def read_portfolio(filename, **opts):
'''
Read a stock portfolio file into a list of dictionaries with keys
name, shares, and price.
'''
with open(filename) as lines:
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
portfolio = [ Stock(**d) for d in portdicts ]
return Portfolio(portfolio)
and the portfolio.py file defines Portfolio() with an odd initializer
like this:
class Portfolio:
def __init__(self, holdings):
self.holdings = holdings
...
Frankly, the chain of responsibility is all a bit confusing because the
code is scattered. If a Portfolio class is supposed to contain
a list of Stock instances, maybe you should change the class to be a bit more clear.
Like this:
# portfolio.py
import stock
class Portfolio:
def __init__(self):
self.holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self.holdings.append(holding)
...
If you want to read a portfolio from a CSV file, maybe you should make a class method for it:
# portfolio.py
import fileparse
import stock
class Portfolio:
def __init__(self):
self.holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self.holdings.append(holding)
@classmethod
def from_csv(cls, lines, **opts):
self = cls()
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
for d in portdicts:
self.append(stock.Stock(**d))
return self
To use this new Portfolio class, you can now write code like this:
>>> from portfolio import Portfolio
>>> with open('Data/portfolio.csv') as lines:
... port = Portfolio.from_csv(lines)
...
>>>
Make these changes to the Portfolio class and modify the report.py
code to use the class method.
Contents | Previous (7.4 Decorators) | Next (8 Testing and Debugging)