Skip to content

Commit 5b6f15d

Browse files
committed
Added solution code
1 parent 960d4fa commit 5b6f15d

136 files changed

Lines changed: 5821 additions & 343 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Notes/04_Classes_objects/01_Class.md

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,15 @@ If you want to operate on an instance, you always have to refer too it explicitl
136136

137137
## Exercises
138138

139+
Note: For this exercise you want to have fully working code from earlier
140+
exercises. If things are broken look at the solution code for Exercise 3.18.
141+
You can find this code in the `Solutions/3_18` directory.
142+
139143
### Exercise 4.1: Objects as Data Structures
140144

141-
In section 2 and 3, we worked with data represented as tuples and dictionaries.
142-
For example, a holding of stock could be represented as a tuple like this:
145+
In section 2 and 3, we worked with data represented as tuples and
146+
dictionaries. For example, a holding of stock could be represented as
147+
a tuple like this:
143148

144149
```python
145150
s = ('GOOG',100,490.10)
@@ -154,125 +159,130 @@ s = { 'name' : 'GOOG',
154159
}
155160
```
156161

157-
You can even write functions for manipulating such data. For example:
162+
You can even write functions for manipulating such data. For example:
158163

159164
```python
160165
def cost(s):
161166
return s['shares'] * s['price']
162167
```
163168

164-
However, as your program gets large, you might want to create a better sense of organization.
165-
Thus, another approach for representing data would be to define a class.
166-
167-
Create a file called `stock.py` and define a class `Stock` that represents a single holding of stock.
168-
Have the instances of `Stock` have `name`, `shares`, and `price` attributes.
169+
However, as your program gets large, you might want to create a better
170+
sense of organization. Thus, another approach for representing data
171+
would be to define a class. Create a file called `stock.py` and
172+
define a class `Stock` that represents a single holding of stock.
173+
Have the instances of `Stock` have `name`, `shares`, and `price`
174+
attributes. For example:
169175

170176
```python
171177
>>> import stock
172-
>>> s = stock.Stock('GOOG',100,490.10)
173-
>>> s.name
178+
>>> a = stock.Stock('GOOG',100,490.10)
179+
>>> a.name
174180
'GOOG'
175-
>>> s.shares
181+
>>> a.shares
176182
100
177-
>>> s.price
183+
>>> a.price
178184
490.1
179185
>>>
180186
```
181187

182-
Create a few more `Stock` objects and manipulate them. For example:
188+
Create a few more `Stock` objects and manipulate them. For example:
183189

184190
```python
185-
>>> a = stock.Stock('AAPL',50,122.34)
186-
>>> b = stock.Stock('IBM',75,91.75)
187-
>>> a.shares * a.price
188-
6117.0
191+
>>> b = stock.Stock('AAPL', 50, 122.34)
192+
>>> c = stock.Stock('IBM', 75, 91.75)
189193
>>> b.shares * b.price
194+
6117.0
195+
>>> c.shares * c.price
190196
6881.25
191-
>>> stocks = [a,b,s]
197+
>>> stocks = [a, b, c]
192198
>>> stocks
193199
[<stock.Stock object at 0x37d0b0>, <stock.Stock object at 0x37d110>, <stock.Stock object at 0x37d050>]
194-
>>> for t in stocks:
195-
print(f'{t.name:>10s} {t.shares:>10d} {t.price:>10.2f}')
200+
>>> for s in stocks:
201+
print(f'{s.name:>10s} {s.shares:>10d} {s.price:>10.2f}')
196202

197203
... look at the output ...
198204
>>>
199205
```
200206

201-
One thing to emphasize here is that the class `Stock` acts like a factory for creating instances of objects.
202-
Basically, you just call it as a function and it creates a new object for you.
207+
One thing to emphasize here is that the class `Stock` acts like a
208+
factory for creating instances of objects. Basically, you call
209+
it as a function and it creates a new object for you. Also, it needs
210+
to be emphasized that each object is distinct---they each have their
211+
own data that is separate from other objects that have been created.
203212

204-
Also, it needs to be emphasized that each object is distinct---they
205-
each have their own data that is separate from other objects that have
206-
been created. An object defined by a class is somewhat similar to a
207-
dictionary, just with somewhat different syntax.
208-
For example, instead of writing `s['name']` or `s['price']`, you now
209-
write `s.name` and `s.price`.
213+
An object defined by a class is somewhat similar to a dictionary--just
214+
with somewhat different syntax. For example, instead of writing
215+
`s['name']` or `s['price']`, you now write `s.name` and `s.price`.
210216

211-
### Exercise 4.2: Reading Data into a List of Objects
217+
### Exercise 4.2: Adding some Methods
212218

213-
In your `stock.py` program, write a function
214-
`read_portfolio(filename)` that reads portfolio data from a file into
215-
a list of `Stock` objects. This function is going to mimic the
216-
behavior of earlier code you have written. Here’s how your function
217-
will behave:
219+
With classes, you can attach functions to your objects. These are
220+
known as methods and are functions that operate on the data
221+
stored inside an object. Add a `cost()` and `sell()` method to your
222+
`Stock` object. They should work like this:
218223

219224
```python
220225
>>> import stock
221-
>>> portfolio = stock.read_portfolio('Data/portfolio.csv')
222-
>>> portfolio
223-
[<stock.Stock object at 0x81d70>, <stock.Stock object at 0x81cf0>, <stock.Stock object at 0x81db0>,
224-
<stock.Stock object at 0x81df0>, <stock.Stock object at 0x81e30>, <stock.Stock object at 0x81e70>,
225-
<stock.Stock object at 0x81eb0>]
226+
>>> s = stock.Stock('GOOG', 100, 490.10)
227+
>>> s.cost()
228+
49010.0
229+
>>> s.shares
230+
100
231+
>>> s.sell(25)
232+
>>> s.shares
233+
75
234+
>>> s.cost()
235+
36757.5
226236
>>>
227237
```
228238

229-
It is important to emphasize that `read_portfolio()` is a top-level function, not a method of the `Stock` class.
230-
This function is merely creating a list of `Stock` objects; it’s not an operation on an individual `Stock` instance.
231-
232-
Try performing some calculations with the above data. First, try printing a formatted table:
233-
234-
```python
235-
>>> for s in portfolio:
236-
print(f'{s.name:>10s} {s.shares:>10d} {s.price:>10.2f}')
237-
238-
... look at the output ...
239-
>>>
240-
```
239+
### Exercise 4.3: Creating a list of instances
241240

242-
Try a list comprehension:
241+
Try these steps to make a list of Stock instances and compute the total
242+
cost:
243243

244244
```python
245-
>>> more100 = [s for s in portfolio if s.shares > 100]
246-
>>> for s in more100:
247-
print(f'{s.name:>10s} {s.shares:>10d} {s.price:>10.2f}')
248-
249-
... look at the output ...
245+
>>> import fileparse
246+
>>> with open('Data/portfolio.csv') as lines:
247+
... portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float])
248+
...
249+
>>> portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts]
250+
>>> portfolio
251+
[<stock.Stock object at 0x10c9e2128>, <stock.Stock object at 0x10c9e2048>, <stock.Stock object at 0x10c9e2080>,
252+
<stock.Stock object at 0x10c9e25f8>, <stock.Stock object at 0x10c9e2630>, <stock.Stock object at 0x10ca6f748>,
253+
<stock.Stock object at 0x10ca6f7b8>]
254+
>>> sum([s.cost() for s in portfolio])
255+
44671.15
250256
>>>
251-
```
257+
----
252258

253-
Again, notice the similarity between `Stock` objects and dictionaries. They’re basically the same idea, but the syntax for accessing values differs.
259+
### Exercise 4.4: Using your class
254260

255-
### Exercise 4.3: Adding some Methods
261+
Modify the `read_portfolio()` function in the `report.py` program so that it
262+
reads a portfolio into a list of `Stock` instances. Once you have done that,
263+
fix all of the code in `report.py` and `pcost.py` so that it works with
264+
`Stock` instances instead of dictionaries.
256265

257-
With classes, you can attach functions to your objects. These are
258-
known as methods and are functions that operate on the data stored
259-
inside an object.
266+
Hint: You should not have to make major changes to the code. You will mainly
267+
be changing dictionary access such as `s['shares']` into `s.shares`.
260268

261-
Add a `cost()` and `sell()` method to your `Stock` object. They should
262-
work like this:
269+
You should be able to run your functions the same as before:
263270

264271
```python
265-
>>> import stock
266-
>>> s = stock.Stock('GOOG',100,490.10)
267-
>>> s.cost()
268-
49010.0
269-
>>> s.shares
270-
100
271-
>>> s.sell(25)
272-
>>> s.shares
273-
75
274-
>>> s.cost()
275-
36757.5
272+
>>> import pcost
273+
>>> pcost.portfolio_cost('Data/portfolio.csv')
274+
44671.15
275+
>>> import report
276+
>>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv')
277+
Name Shares Price Change
278+
---------- ---------- ---------- ----------
279+
AA 100 9.22 -22.98
280+
IBM 50 106.28 15.18
281+
CAT 150 35.46 -47.98
282+
MSFT 200 20.89 -30.34
283+
GE 95 13.48 -26.89
284+
MSFT 50 20.89 -44.21
285+
IBM 100 106.28 35.84
276286
>>>
277287
```
278288

0 commit comments

Comments
 (0)