Links and renumbering
This commit is contained in:
@@ -110,7 +110,7 @@ If you want to operate on an instance, you always have to refer too it explicitl
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Objects as Data Structures
|
||||
### Exercise 4.1: Objects as Data Structures
|
||||
|
||||
In section 2 and 3, we worked with data represented as tuples and dictionaries.
|
||||
For example, a holding of stock could be represented as a tuple like this:
|
||||
@@ -182,7 +182,7 @@ dictionary, just with somewhat different syntax.
|
||||
For example, instead of writing `s['name']` or `s['price']`, you now
|
||||
write `s.name` and `s.price`.
|
||||
|
||||
### (b) Reading Data into a List of Objects
|
||||
### Exercise 4.2: Reading Data into a List of Objects
|
||||
|
||||
In your `stock.py` program, write a function
|
||||
`read_portfolio(filename)` that reads portfolio data from a file into
|
||||
@@ -226,7 +226,7 @@ Try a list comprehension:
|
||||
|
||||
Again, notice the similarity between `Stock` objects and dictionaries. They’re basically the same idea, but the syntax for accessing values differs.
|
||||
|
||||
### (c) Adding some Methods
|
||||
### Exercise 4.3: Adding some Methods
|
||||
|
||||
With classes, you can attach functions to your objects. These are
|
||||
known as methods and are functions that operate on the data stored
|
||||
@@ -250,4 +250,4 @@ work like this:
|
||||
>>>
|
||||
```
|
||||
|
||||
[Next](02_Inheritance)
|
||||
[Contents](../Contents) \| [Previous (3.6 Design discussion)](../03_Program_organization/06_Design_discussion) \| [Next (4.2 Inheritance)](02_Inheritance)
|
||||
|
||||
@@ -220,7 +220,7 @@ We're not going to explore multiple inheritance further in this course.
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Print Portfolio
|
||||
### Exercise 4.4: Print Portfolio
|
||||
|
||||
A major use of inheritance is in writing code that’s meant to be extended or customized in various ways—especially in libraries or frameworks.
|
||||
To illustrate, start by adding the following function to your `stock.py` program:
|
||||
@@ -263,7 +263,7 @@ When you run your `stock.py`, you should get this output:
|
||||
IBM 100 70.44
|
||||
```
|
||||
|
||||
### (b) An Extensibility Problem
|
||||
### Exercise 4.5: An Extensibility Problem
|
||||
|
||||
Suppose that you wanted to modify the `print_portfolio()` function to
|
||||
support a variety of different output formats such as plain-text,
|
||||
@@ -329,7 +329,7 @@ if __name__ == '__main__':
|
||||
When you run this new code, your program will immediately crash with a `NotImplementedError` exception.
|
||||
That’s not too exciting, but continue to the next part.
|
||||
|
||||
### (c) Using Inheritance to Produce Different Output
|
||||
### 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:
|
||||
@@ -430,7 +430,7 @@ Using a similar idea, define a class `HTMLTableFormatter` that produces a table
|
||||
|
||||
Test your code by modifying the main program to create a `HTMLTableFormatter` object instead of a `CSVTableFormatter` object.
|
||||
|
||||
### (d) Polymorphism in Action
|
||||
### Exercise 4.7: Polymorphism in Action
|
||||
|
||||
A major feature of object-oriented programming is that you can plug an
|
||||
object into a program and it will work without having to change any of
|
||||
@@ -499,4 +499,4 @@ That said, understanding what happened in this exercise will take you
|
||||
pretty far in terms of using most library modules and knowing
|
||||
what inheritance is good for (extensibility).
|
||||
|
||||
[Next](03_Special_methods)
|
||||
[Contents](../Contents) \| [Previous (4.1 Classes)](01_Class) \| [Next (4.3 Special methods)](03_Special_methods)
|
||||
|
||||
@@ -202,7 +202,7 @@ x = getattr(obj, 'x', None)
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Better output for printing objects
|
||||
### Exercise 4.8: Better output for printing objects
|
||||
|
||||
All Python objects have two string representations. The first
|
||||
representation is created by string conversion via `str()` (which is
|
||||
@@ -248,7 +248,7 @@ See what happens when you read a portfolio of stocks and view the resulting list
|
||||
>>>
|
||||
```
|
||||
|
||||
### (b) An example of using `getattr()`
|
||||
### Exercise 4.9: An example of using `getattr()`
|
||||
|
||||
In Exercise 4.2 you worked with a function `print_portfolio()` that made a table for a stock portfolio.
|
||||
That function was hard-coded to only work with stock data—-how limiting! You can do so much more if you use functions such as `getattr()`.
|
||||
@@ -306,7 +306,7 @@ format. Here’s how it should work:
|
||||
>>>
|
||||
```
|
||||
|
||||
### (c) Exercise Bonus: Column Formatting
|
||||
### Exercise 4.10: Exercise Bonus: Column Formatting
|
||||
|
||||
Modify the `print_table()` function in part (B) so that it also
|
||||
accepts a list of format specifiers for formatting the contents of
|
||||
@@ -329,4 +329,5 @@ each column.
|
||||
>>>
|
||||
```
|
||||
|
||||
[Next](04_Defining_exceptions)
|
||||
[Contents](../Contents) \| [Previous (4.2 Inheritance)](02_Inheritance) \| [Next (4.4 Exceptions)](04_Defining_exceptions)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class ProtocolError(NetworkError):
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Defining a custom exception
|
||||
### Exercise 4.11: Defining a custom exception
|
||||
|
||||
It is often good practice for libraries to define their own exceptions.
|
||||
|
||||
@@ -47,3 +47,5 @@ Traceback (most recent call last):
|
||||
FormatError: Unknown table format xls
|
||||
>>>
|
||||
```
|
||||
|
||||
[Contents](../Contents) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview)
|
||||
|
||||
@@ -362,10 +362,10 @@ Frameworks / libraries sometimes use it for advanced features involving composit
|
||||
|
||||
## Exercises
|
||||
|
||||
In Exercise 4.1, you defined a class `Stock` that represented a holding of stock.
|
||||
In Section 4, you defined a class `Stock` that represented a holding of stock.
|
||||
In this exercise, we will use that class.
|
||||
|
||||
### (a) Representation of Instances
|
||||
### Exercise 5.1: Representation of Instances
|
||||
|
||||
At the interactive shell, inspect the underlying dictionaries of the two instances you created:
|
||||
|
||||
@@ -380,7 +380,7 @@ At the interactive shell, inspect the underlying dictionaries of the two instanc
|
||||
>>>
|
||||
```
|
||||
|
||||
### (b) Modification of Instance Data
|
||||
### Exercise 5.2: Modification of Instance Data
|
||||
|
||||
Try setting a new attribute on one of the above instances:
|
||||
|
||||
@@ -412,7 +412,7 @@ top of a dictionary. *Note: it should be emphasized that direct
|
||||
manipulation of the dictionary is uncommon—you should always write
|
||||
your code to use the (.) syntax.*
|
||||
|
||||
### (c) The role of classes
|
||||
### Exercise 5.3: The role of classes
|
||||
|
||||
The definitions that make up a class definition are shared by all instances of that class.
|
||||
Notice, that all instances have a link back to their associated class:
|
||||
@@ -517,7 +517,7 @@ It is shared by all of the instances that get created.
|
||||
>>>
|
||||
```
|
||||
|
||||
### (d) Bound Methods
|
||||
### Exercise 5.4: Bound Methods
|
||||
|
||||
A subtle feature of Python is that invoking a method actually involves
|
||||
two steps and something known as a bound method.
|
||||
@@ -568,7 +568,7 @@ For example, calling `s(25)` actually does this:
|
||||
>>>
|
||||
```
|
||||
|
||||
### (e) Inheritance
|
||||
### Exercise 5.5: Inheritance
|
||||
|
||||
Make a new class that inherits from `Stock`.
|
||||
|
||||
@@ -617,4 +617,5 @@ Here’s how the `cost()` method of instance `n` above would be found:
|
||||
>>>
|
||||
```
|
||||
|
||||
[Next](02_Classes_encapsulation)
|
||||
[Contents](../Contents) \| [Previous (4.4 Exceptions)](../04_Classes_objects/04_Defining_exceptions) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation)
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ day-to-day coding.
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Simple properties
|
||||
### Exercise 5.6: Simple properties
|
||||
|
||||
Properties are a useful way to add "computed attributes" to an object.
|
||||
In Exercise 4.1, you created an object `Stock`. Notice that on your
|
||||
@@ -289,7 +289,7 @@ Try calling `s.cost()` as a function and observe that it doesn’t work now that
|
||||
>>>
|
||||
```
|
||||
|
||||
### (b) Properties and Setters
|
||||
### Exercise 5.7: Properties and Setters
|
||||
|
||||
Modify the `shares` attribute so that the value is stored in a private
|
||||
attribute and that a pair of property functions are used to ensure
|
||||
@@ -306,7 +306,7 @@ TypeError: expected an integer
|
||||
>>>
|
||||
```
|
||||
|
||||
### (c) Adding slots
|
||||
### Exercise 5.8: Adding slots
|
||||
|
||||
Modify the `Stock` class so that it has a `__slots__` attribute.
|
||||
Then, verify that new attributes can’t be added:
|
||||
@@ -333,3 +333,5 @@ What happens if you try to inspect the underlying dictionary of `s` above?
|
||||
It should be noted that `__slots__` is most commonly used as an
|
||||
optimization on classes that serve as data structures. Using slots
|
||||
will make such programs use far-less memory and run a bit faster.
|
||||
|
||||
[Contents](../Contents) \| [Previous (5.1 Dictionaries Revisited)](01_Dicts_revisited) \| [Next (6 Generators)](../06_Generators/00_Overview)
|
||||
|
||||
@@ -86,7 +86,7 @@ for s in port:
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) Iteration Illustrated
|
||||
### Exercise 6.1: Iteration Illustrated
|
||||
|
||||
Create the following list:
|
||||
|
||||
@@ -137,7 +137,7 @@ the `__next__()` method of an iterator. Try using it on a file:
|
||||
Keep calling `next(f)` until you reach the end of the
|
||||
file. Watch what happens.
|
||||
|
||||
### (b) Supporting Iteration
|
||||
### Exercise 6.2: Supporting Iteration
|
||||
|
||||
On occasion, you might want to make one of your own objects support
|
||||
iteration--especially if your object wraps around an existing
|
||||
@@ -249,7 +249,7 @@ Test it to make sure it works:
|
||||
>>>
|
||||
```
|
||||
|
||||
### (d) Making a more proper container
|
||||
### Exercise 6.3: Making a more proper container
|
||||
|
||||
If making a container class, you often want to do more than just
|
||||
iteration. Modify the `Portfolio` class so that it has some other
|
||||
@@ -310,4 +310,4 @@ Python normally work. For container objects, supporting iteration,
|
||||
indexing, containment, and other kinds of operators is an important
|
||||
part of this.
|
||||
|
||||
[Next](02_Customizing_iteration)
|
||||
[Contents](../Contents) \| [Previous (5.2 Encapsulation)](../05_Classes_objects/02_Classes_encapsulation) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration)
|
||||
|
||||
@@ -99,7 +99,7 @@ File "<stdin>", line 1, in ? StopIteration
|
||||
|
||||
## Exercises
|
||||
|
||||
### (a) A Simple Generator
|
||||
### Exercise 6.4: A Simple Generator
|
||||
|
||||
If you ever find yourself wanting to customize iteration, you should
|
||||
always think generator functions. They're easy to write---make
|
||||
@@ -139,7 +139,7 @@ This is kind of interesting--the idea that you can hide a bunch of
|
||||
custom processing in a function and use it to feed a for-loop.
|
||||
The next example looks at a more unusual case.
|
||||
|
||||
### (b) Monitoring a streaming data source
|
||||
### Exercise 6.5: Monitoring a streaming data source
|
||||
|
||||
Generators can be an interesting way to monitor real-time data sources
|
||||
such as log files or stock market feeds. In this part, we'll
|
||||
@@ -197,7 +197,7 @@ this case, we are using it to repeatedly probe the end of the file to
|
||||
see if more data has been added (`readline()` will either
|
||||
return new data or an empty string).
|
||||
|
||||
### (c) Using a generator to produce data
|
||||
### Exercise 6.6: Using a generator to produce data
|
||||
|
||||
If you look at the code in part (b), the first part of the code is producing
|
||||
lines of data whereas the statements at the end of the `while` loop are consuming
|
||||
@@ -229,7 +229,7 @@ if __name__ == '__main__':
|
||||
print(f'{name:>10s} {price:>10.2f} {change:>10.2f}')
|
||||
```
|
||||
|
||||
### (d) Watching your portfolio
|
||||
### Exercise 6.7: Watching your portfolio
|
||||
|
||||
Modify the `follow.py` program so that it watches the stream of stock
|
||||
data and prints a ticker showing information for only those stocks
|
||||
@@ -262,4 +262,4 @@ is now this completely general purpose utility that you can use in any program.
|
||||
example, you could use it to watch server logs, debugging logs, and other similar data sources.
|
||||
That's kind of cool.
|
||||
|
||||
[Next](03_Producers_consumers)
|
||||
[Contents](../Contents) \| [Previous (6.1 Iteration Protocol)](01_Iteration_protocol) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers)
|
||||
|
||||
@@ -101,7 +101,7 @@ You will notice that data incrementally flows through the different functions.
|
||||
For this exercise the `stocksim.py` program should still be running in the background.
|
||||
You’re going to use the `follow()` function you wrote in the previous exercise.
|
||||
|
||||
### (a) Setting up a simple pipeline
|
||||
### Exercise 6.8: Setting up a simple pipeline
|
||||
|
||||
Let's see the pipelining idea in action. Write the following
|
||||
function:
|
||||
@@ -132,7 +132,7 @@ to it as an argument. Now, try this:
|
||||
It might take awhile for output to appear, but eventually you
|
||||
should see some lines containing data for IBM.
|
||||
|
||||
### (b) Setting up a more complex pipeline
|
||||
### Exercise 6.9: Setting up a more complex pipeline
|
||||
|
||||
Take the pipelining idea a few steps further by performing
|
||||
more actions.
|
||||
@@ -156,7 +156,7 @@ Well, that's interesting. What you're seeing here is that the output of the
|
||||
`follow()` function has been piped into the `csv.reader()` function and we're
|
||||
now getting a sequence of split rows.
|
||||
|
||||
### (c) Making more pipeline components
|
||||
### Exercise 6.10: Making more pipeline components
|
||||
|
||||
Let's extend the whole idea into a larger pipeline. In a separate file `ticker.py`,
|
||||
start by creating a function that reads a CSV file as you did above:
|
||||
@@ -237,7 +237,7 @@ Run your program again. You should now a stream of dictionaries like this:
|
||||
...
|
||||
```
|
||||
|
||||
### (d) Filtering data
|
||||
### Exercise 6.11: Filtering data
|
||||
|
||||
Write a function that filters data. For example:
|
||||
|
||||
@@ -262,7 +262,7 @@ for row in rows:
|
||||
print(row)
|
||||
```
|
||||
|
||||
### (e) Putting it all together
|
||||
### Exercise 6.12: Putting it all together
|
||||
|
||||
In the `ticker.py` program, write a function `ticker(portfile, logfile, fmt)`
|
||||
that creates a real-time stock ticker from a given portfolio, logfile,
|
||||
@@ -296,6 +296,6 @@ pipelines. In addition, you can create functions that package a
|
||||
series of pipeline stages into a single function call (for example,
|
||||
the `parse_stock_data()` function).
|
||||
|
||||
[Next](04_More_generators)
|
||||
[Contents](../Contents) \| [Previous (6.2 Customizing Iteration)](02_Customizing_iteration) \| [Next (6.4 Generator Expressions)](04_More_generators)
|
||||
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ More information at [Generator Tricks for Systems Programmers](http://www.dabeaz
|
||||
In the previous exercises, you wrote some code that followed lines being written to a log file and parsed them into a sequence of rows.
|
||||
This exercise continues to build upon that. Make sure the `Data/stocksim.py` is still running.
|
||||
|
||||
### (a) Generator Expressions
|
||||
### Exercise 6.13: Generator Expressions
|
||||
|
||||
Generator expressions are a generator version of a list comprehension.
|
||||
For example:
|
||||
@@ -134,7 +134,7 @@ Thus, if you try another for-loop, you get nothing:
|
||||
>>>
|
||||
```
|
||||
|
||||
### (b) Generator Expressions in Function Arguments
|
||||
### Exercise 6.14: Generator Expressions in Function Arguments
|
||||
|
||||
Generator expressions are sometimes placed into function arguments.
|
||||
It looks a little weird at first, but try this experiment:
|
||||
@@ -154,7 +154,7 @@ In your `portfolio.py` file, you performed a few calculations
|
||||
involving list comprehensions. Try replacing these with
|
||||
generator expressions.
|
||||
|
||||
### (c) Code simplification
|
||||
### Exercise 6.15: Code simplification
|
||||
|
||||
Generators expressions are often a useful replacement for
|
||||
small generator functions. For example, instead of writing a
|
||||
@@ -177,3 +177,4 @@ Modify the `ticker.py` program to use generator expressions
|
||||
as appropriate.
|
||||
|
||||
|
||||
[Contents](../Contents) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview)
|
||||
Reference in New Issue
Block a user