Links and renumbering

This commit is contained in:
David Beazley
2020-05-26 15:30:14 -05:00
parent 9c032f7a23
commit 45c7ec1f4a
10 changed files with 49 additions and 42 deletions

View File

@@ -110,7 +110,7 @@ If you want to operate on an instance, you always have to refer too it explicitl
## Exercises ## 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. 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: 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 For example, instead of writing `s['name']` or `s['price']`, you now
write `s.name` and `s.price`. 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 In your `stock.py` program, write a function
`read_portfolio(filename)` that reads portfolio data from a file into `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. Theyre basically the same idea, but the syntax for accessing values differs. Again, notice the similarity between `Stock` objects and dictionaries. Theyre 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 With classes, you can attach functions to your objects. These are
known as methods and are functions that operate on the data stored 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)

View File

@@ -220,7 +220,7 @@ We're not going to explore multiple inheritance further in this course.
## Exercises ## Exercises
### (a) Print Portfolio ### Exercise 4.4: Print Portfolio
A major use of inheritance is in writing code thats meant to be extended or customized in various ways—especially in libraries or frameworks. A major use of inheritance is in writing code thats 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: 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 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 Suppose that you wanted to modify the `print_portfolio()` function to
support a variety of different output formats such as plain-text, 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. When you run this new code, your program will immediately crash with a `NotImplementedError` exception.
Thats not too exciting, but continue to the next part. Thats 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. The `TableFormatter` class you defined in part (a) is meant to be extended via inheritance.
In fact, thats the whole idea. To illustrate, define a class `TextTableFormatter` like this: In fact, thats 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. 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 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 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 pretty far in terms of using most library modules and knowing
what inheritance is good for (extensibility). 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)

View File

@@ -202,7 +202,7 @@ x = getattr(obj, 'x', None)
## Exercises ## Exercises
### (a) Better output for printing objects ### Exercise 4.8: Better output for printing objects
All Python objects have two string representations. The first All Python objects have two string representations. The first
representation is created by string conversion via `str()` (which is 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. 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()`. 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. Heres 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 Modify the `print_table()` function in part (B) so that it also
accepts a list of format specifiers for formatting the contents of 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)

View File

@@ -22,7 +22,7 @@ class ProtocolError(NetworkError):
## Exercises ## 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. 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 FormatError: Unknown table format xls
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview)

View File

@@ -362,10 +362,10 @@ Frameworks / libraries sometimes use it for advanced features involving composit
## Exercises ## 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. 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: 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: 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 manipulation of the dictionary is uncommon—you should always write
your code to use the (.) syntax.* 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. 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: 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 A subtle feature of Python is that invoking a method actually involves
two steps and something known as a bound method. 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`. Make a new class that inherits from `Stock`.
@@ -617,4 +617,5 @@ Heres 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)

View File

@@ -252,7 +252,7 @@ day-to-day coding.
## Exercises ## Exercises
### (a) Simple properties ### Exercise 5.6: Simple properties
Properties are a useful way to add "computed attributes" to an object. 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 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 doesnt 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 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 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. Modify the `Stock` class so that it has a `__slots__` attribute.
Then, verify that new attributes cant be added: Then, verify that new attributes cant 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 It should be noted that `__slots__` is most commonly used as an
optimization on classes that serve as data structures. Using slots optimization on classes that serve as data structures. Using slots
will make such programs use far-less memory and run a bit faster. 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)

View File

@@ -86,7 +86,7 @@ for s in port:
## Exercises ## Exercises
### (a) Iteration Illustrated ### Exercise 6.1: Iteration Illustrated
Create the following list: 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 Keep calling `next(f)` until you reach the end of the
file. Watch what happens. 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 On occasion, you might want to make one of your own objects support
iteration--especially if your object wraps around an existing 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 If making a container class, you often want to do more than just
iteration. Modify the `Portfolio` class so that it has some other 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 indexing, containment, and other kinds of operators is an important
part of this. 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)

View File

@@ -99,7 +99,7 @@ File "<stdin>", line 1, in ? StopIteration
## Exercises ## Exercises
### (a) A Simple Generator ### Exercise 6.4: A Simple Generator
If you ever find yourself wanting to customize iteration, you should If you ever find yourself wanting to customize iteration, you should
always think generator functions. They're easy to write---make 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. custom processing in a function and use it to feed a for-loop.
The next example looks at a more unusual case. 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 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 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 see if more data has been added (`readline()` will either
return new data or an empty string). 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 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 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}') 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 Modify the `follow.py` program so that it watches the stream of stock
data and prints a ticker showing information for only those stocks 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. example, you could use it to watch server logs, debugging logs, and other similar data sources.
That's kind of cool. 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)

View File

@@ -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. For this exercise the `stocksim.py` program should still be running in the background.
Youre going to use the `follow()` function you wrote in the previous exercise. Youre 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 Let's see the pipelining idea in action. Write the following
function: function:
@@ -132,7 +132,7 @@ to it as an argument. Now, try this:
It might take awhile for output to appear, but eventually you It might take awhile for output to appear, but eventually you
should see some lines containing data for IBM. 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 Take the pipelining idea a few steps further by performing
more actions. 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 `follow()` function has been piped into the `csv.reader()` function and we're
now getting a sequence of split rows. 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`, 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: 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: Write a function that filters data. For example:
@@ -262,7 +262,7 @@ for row in rows:
print(row) 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)` In the `ticker.py` program, write a function `ticker(portfile, logfile, fmt)`
that creates a real-time stock ticker from a given portfolio, logfile, 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, series of pipeline stages into a single function call (for example,
the `parse_stock_data()` function). 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)

View File

@@ -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. 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. 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. Generator expressions are a generator version of a list comprehension.
For example: 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. Generator expressions are sometimes placed into function arguments.
It looks a little weird at first, but try this experiment: 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 involving list comprehensions. Try replacing these with
generator expressions. generator expressions.
### (c) Code simplification ### Exercise 6.15: Code simplification
Generators expressions are often a useful replacement for Generators expressions are often a useful replacement for
small generator functions. For example, instead of writing a small generator functions. For example, instead of writing a
@@ -177,3 +177,4 @@ Modify the `ticker.py` program to use generator expressions
as appropriate. as appropriate.
[Contents](../Contents) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview)