diff --git a/Exercises/README.md b/Exercises/README.md index 533dd773..c31bbb9e 100644 --- a/Exercises/README.md +++ b/Exercises/README.md @@ -13,18 +13,18 @@ This course requires the use of Python 3.6 or newer. If you are using Python 2, most of the material still applies, but you will have to make minor code modifications here and there. -- link:PythonMastery.pdf[`PythonMastery.pdf`] is a PDF that contains +- [`PythonMastery.pdf`](../PythonMastery.pdf) is a PDF that contains all of the presentation slides. -- The link:Exercises/index.html[`Exercises/`] folder is where you +- The [`Exercises/`](index.md) folder is where you find all the class exercises. -- The `Data/` folder is where you find data files, scripts, and +- The [`Data/`](../Data/) folder is where you find data files, scripts, and other files used by the exercises. -- The `Solutions/` folder contains complete solution code for +- The [`Solutions/`](../Solutions/) folder contains complete solution code for various exercises. Each problem has its own directory. For example, -the solution to exercise 3.2 can be found in the `Solution/3_2/` directory. +the solution to exercise 3.2 can be found in the [`Solutions/3_2/`](../Solutions/3_2/) directory. Every attempt has been made to make sure exercises work. However, it's possible that you will find typos or minor mistakes. If you find any diff --git a/Exercises/ex2_3.md b/Exercises/ex2_3.md index ecc32652..6ca5eea8 100644 --- a/Exercises/ex2_3.md +++ b/Exercises/ex2_3.md @@ -310,7 +310,7 @@ you do need to make sure you don't go overboard with the syntax. ## (f) Saving a lot of memory -In link:ex2_1.html[Exercise 2.1] you wrote a function +In [Exercise 2.1](ex2_1.md) you wrote a function `read_rides_as_dicts()` that read the CTA bus data into a list of dictionaries. Using it requires a lot of memory. For example, let's find the day on which the route 22 bus had the greatest diff --git a/Exercises/ex3_1.md b/Exercises/ex3_1.md index 37b1c3df..9acb8d1b 100644 --- a/Exercises/ex3_1.md +++ b/Exercises/ex3_1.md @@ -8,7 +8,7 @@ *Files Modified:* `stock.py` -In link:ex1_5.html[Exercise 1.5], you defined a simple class +In [Exercise 1.5](ex1_5.md), you defined a simple class `Stock` for representing a holding of stock. In this exercise, we're simply going to add a few features to that class as well as write some utility functions. @@ -49,7 +49,7 @@ reads a file of portfolio data into a list of `Stock` objects. Here's how it sho ``` You already wrote a similar function as part of -link:ex2_3.html[Exercise 2.3]. Design discussion: Should +[Exercise 2.3](ex2_3.md). Design discussion: Should `read_portfolio()` be a separate function or part of the class definition? diff --git a/Exercises/ex3_2.md b/Exercises/ex3_2.md index 3954fd70..9886b518 100644 --- a/Exercises/ex3_2.md +++ b/Exercises/ex3_2.md @@ -66,7 +66,7 @@ price 490.1 ## (c) Table Output -In link:ex3_1.html[Exercise 3.1], you wrote a function `print_portfolio()` +In [Exercise 3.1](ex3_1.md), you wrote a function `print_portfolio()` that made a nicely formatted table. That function was custom tailored to a list of `Stock` objects. However, it can be completely generalized to work with any list of objects using the technique in part (b). diff --git a/Exercises/ex3_5.md b/Exercises/ex3_5.md index 5932adad..1a2dd4c1 100644 --- a/Exercises/ex3_5.md +++ b/Exercises/ex3_5.md @@ -13,7 +13,7 @@ CSV, and HTML. One major use of classes in Python is in writing code that be extended/adapted in various ways. To illustrate, in -link:ex3_2.html[Exercise 3.2] you created a function `print_table()` +[Exercise 3.2](ex3_2.md) you created a function `print_table()` that made tables. You used this to make output from the `portfolio` list. For example: diff --git a/Exercises/ex3_6.md b/Exercises/ex3_6.md index cc619aac..cd01a329 100644 --- a/Exercises/ex3_6.md +++ b/Exercises/ex3_6.md @@ -98,7 +98,7 @@ Make this change and try comparing two objects again. ## (c) A Context Manager -In link:ex3_5.html[Exercise 3.5], you made it possible for users to make +In [Exercise 3.5](ex3_5.md), you made it possible for users to make nicely formatted tables. For example: ```python diff --git a/Exercises/ex3_7.md b/Exercises/ex3_7.md index a860e878..f01e1e1a 100644 --- a/Exercises/ex3_7.md +++ b/Exercises/ex3_7.md @@ -9,7 +9,7 @@ *Files Modified:* `tableformat.py` -In link:ex3_5.html[Exercise 3.5], we modified the `tableformat.py` file to have a `TableFormatter` +In [Exercise 3.5](ex3_5.md), we modified the `tableformat.py` file to have a `TableFormatter` class and to use various subclasses for different output formats. In this exercise, we extend that code a bit more. diff --git a/Exercises/ex3_8.md b/Exercises/ex3_8.md index 4091b25d..a1a278c3 100644 --- a/Exercises/ex3_8.md +++ b/Exercises/ex3_8.md @@ -10,7 +10,7 @@ ## (a) The Trouble with Column Formatting -If you go all the way back to link:ex3_1.txt[Exercise 3.1], you +If you go all the way back to [Exercise 3.1](ex3_1.md), you wrote a function `print_portfolio()` that produced a table like this: ```python @@ -204,7 +204,7 @@ different ways. Using mixins can be a useful tool for framework builders for reducing the amount of code that needs to be written. However, forcing users to remember how to properly compose classes and use multiple inheritance can -fry their brains. In link:ex3_5.html[Exercise 3.5], you wrote a +fry their brains. In [Exercise 3.5](ex3_5.md), you wrote a function `create_formatter()` that made it easier to create a custom formatter. Take that function and extend it to understand a few optional arguments related to the mixin classes. For example: diff --git a/Exercises/ex4_2.md b/Exercises/ex4_2.md index 3b4a12c0..2f7ad81b 100644 --- a/Exercises/ex4_2.md +++ b/Exercises/ex4_2.md @@ -123,7 +123,7 @@ the end of the MRO since it is the parent to all of the classes being composed t ## (b) Build a Value Checker -In link:ex3_4.html[Exercise 3.4], you added some properties to the `Stock` class that +In [Exercise 3.4](ex3_4.md), you added some properties to the `Stock` class that checked attributes for different types and values (e.g., shares had to be a positive integer). Let's play with that idea a bit. Start by creating a file `validate.py` and defining the following base class: diff --git a/Exercises/ex6_1.md b/Exercises/ex6_1.md index b3c2bdef..a837a745 100644 --- a/Exercises/ex6_1.md +++ b/Exercises/ex6_1.md @@ -16,7 +16,7 @@ sane way. Before doing anything, copy your work in `stock.py` to a new file `orig_stock.py`. We're going to recreate the `Stock` class from scratch using some new techniques. -Make sure you have your unit tests from link:ex5_4.html[Exercise 5.4] handy. You'll want those. +Make sure you have your unit tests from [Exercise 5.4](ex5_4.md) handy. You'll want those. If you define a function, you probably already know that it can be called using a mix of positional or keyword arguments. For example: diff --git a/Exercises/ex6_3.md b/Exercises/ex6_3.md index 82a567db..c4367fc8 100644 --- a/Exercises/ex6_3.md +++ b/Exercises/ex6_3.md @@ -63,7 +63,7 @@ mappingproxy(OrderedDict([('x', ), ('y', )])) ## (c) Putting it Together -In link:ex6_1.html[Exercise 6.1], you created a class `Structure` +In [Exercise 6.1](ex6_1.md), you created a class `Structure` that defined a generalized `__init__()`, `__setattr__()`, and `__repr__()` method. That class required a user to define a `_fields` class variable like this: @@ -75,7 +75,7 @@ class Stock(Structure): The problem with this class is that the `__init__()` function didn't have a useful argument signature for the purposes of help and -keyword argument passing. In link:ex6_2.html[Exercise 6.2], you +keyword argument passing. In [Exercise 6.2](ex6_2.md), you did a sneaky trick involving a special `self._init()` function. For example: ```python diff --git a/Exercises/ex6_4.md b/Exercises/ex6_4.md index 7ae4b1bb..61370b59 100644 --- a/Exercises/ex6_4.md +++ b/Exercises/ex6_4.md @@ -60,7 +60,7 @@ There are no weird hacks involving a special `_init()` method or stack frames. ## (b) Creating an `__init__()` function -In link:ex6_3.txt[Exercise 6.3], you wrote code that inspected the +In [Exercise 6.3](ex6_3.md), you wrote code that inspected the signature of the `__init__()` method to set the attribute names in a `_fields` class variable. For example: @@ -108,7 +108,7 @@ methods on the `Structure` class--that approach was kind of weird. ## (c) Named Tuples -In link:ex2_1.html[Exercise 2.1], you experimented with `namedtuple` objects +In [Exercise 2.1](ex2_1.md), you experimented with `namedtuple` objects in the `collections` module. Just to refresh your memory, here is how they worked: diff --git a/Exercises/ex7_3.md b/Exercises/ex7_3.md index 4da81da9..42b9a099 100644 --- a/Exercises/ex7_3.md +++ b/Exercises/ex7_3.md @@ -14,7 +14,7 @@ developed over the last few days. Hang on to your hat. ## (a) Descriptors Revisited -In link:ex4_3.html[Exercise 4.3] you defined some descriptors that +In [Exercise 4.3](ex4_3.md) you defined some descriptors that allowed a user to define classes with type-checked attributes like this: @@ -29,7 +29,7 @@ class Stock: ``` Modify your `Stock` class so that it includes the above descriptors -and now looks like this (see link:ex6_4.html[Exercise 6.4]): +and now looks like this (see [Exercise 6.4](ex6_4.md)): ```python # stock.py diff --git a/Exercises/ex7_6.md b/Exercises/ex7_6.md index aae3a226..84b397b7 100644 --- a/Exercises/ex7_6.md +++ b/Exercises/ex7_6.md @@ -11,7 +11,7 @@ ## (a) The Final Frontier -In link:ex7_3.html[Exercise 7.3], we made it possible to define type-checked structures as follows: +In [Exercise 7.3](ex7_3.md), we made it possible to define type-checked structures as follows: ```python from validate import String, PositiveInteger, PositiveFloat diff --git a/Exercises/ex8_3.md b/Exercises/ex8_3.md index d02391b9..334458b6 100644 --- a/Exercises/ex8_3.md +++ b/Exercises/ex8_3.md @@ -13,7 +13,7 @@ For this exercise the `stocksim.py` program should still be running in the background. -In link:ex8_2.html[Exercise 8.2] you wrote some code that used +In [Exercise 8.2](ex8_2.md) you wrote some code that used generators to set up a processing pipeline. A key aspect of that program was the idea of data flowing between generator functions. A very similar kind of dataflow can be set up using coroutines. The @@ -24,7 +24,7 @@ processing elements as opposed to pulling data out with a for-loop. Getting started with coroutines can be a little tricky. Here is an example program that performs the same task as -link:ex8_2.html[Exercise 8.2], but with coroutines. Take this program +[Exercise 8.2](ex8_2.md), but with coroutines. Take this program and copy it into a file called `cofollow.py`. ```python @@ -71,7 +71,7 @@ Run this program and make sure produces output.. Make sure you understand how ## (b) Build some pipeline components In a file `coticker.py`, build a series of pipeline components that carry out the same tasks as -the `ticker.py` program in link:ex8_2.html[Exercise 8.2]. Here is the implementation of the +the `ticker.py` program in [Exercise 8.2](ex8_2.md). Here is the implementation of the various pieces. ```python diff --git a/Exercises/ex8_6.md b/Exercises/ex8_6.md index 2523bc79..30ab0ba1 100644 --- a/Exercises/ex8_6.md +++ b/Exercises/ex8_6.md @@ -19,7 +19,7 @@ clean-up code that relies on generators. ## (a) Example: Receiving messages -In link:ex8_3.html[Exercise 8.3], we looked at the definitions of coroutines. +In [Exercise 8.3](ex8_3.md), we looked at the definitions of coroutines. Coroutines were functions that you sent data to. For example: ```python @@ -80,7 +80,7 @@ is a bit more descriptive--it indicates that the function will yield until it receives a message of a given type. Now, modify all of the coroutines in `coticker.py` to use the new `receive()` -function and make sure the code from link:ex8_3.html[Exercise 8.3] still +function and make sure the code from [Exercise 8.3](ex8_3.md) still works. ## (b) Wrapping a Socket