Fix Broken Links

This commit is contained in:
A D Vishnu Prasad
2020-05-29 19:15:25 +05:30
parent fc9f806d2c
commit bd46830659
53 changed files with 294 additions and 294 deletions

View File

@@ -86,7 +86,7 @@ exercises. Feel free to look at this if you need a hint. To get the
most out of the course however, you should try to create your own most out of the course however, you should try to create your own
solutions first. solutions first.
[Contents](Contents) [Contents](Contents.md)

View File

@@ -3,15 +3,15 @@
The goal of this first section is to introduce some Python basics from The goal of this first section is to introduce some Python basics from
the ground up. Starting with nothing, you'll learn how to edit, run, the ground up. Starting with nothing, you'll learn how to edit, run,
and debug small programs. Ultimately, you'll write a short script that and debug small programs. Ultimately, you'll write a short script that
reads a CSV data file and performs a simple calculation. reads a CSV data file and performs a simple calculation.
* [1.1 Introducing Python](01_Python) * [1.1 Introducing Python](01_Python.md)
* [1.2 A First Program](02_Hello_world) * [1.2 A First Program](02_Hello_world.md)
* [1.3 Numbers](03_Numbers) * [1.3 Numbers](03_Numbers.md)
* [1.4 Strings](04_Strings) * [1.4 Strings](04_Strings.md)
* [1.5 Lists](05_Lists) * [1.5 Lists](05_Lists.md)
* [1.6 Files](06_Files) * [1.6 Files](06_Files.md)
* [1.7 Functions](07_Functions) * [1.7 Functions](07_Functions.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,11 +1,11 @@
[Contents](../Contents) \| [Next (1.2 A First Program)](02_Hello_world) [Contents](../Contents.md) \| [Next (1.2 A First Program)](02_Hello_world.md)
# 1.1 Python # 1.1 Python
### What is Python? ### What is Python?
Python is an interpreted high level programming language. It is often classified as a Python is an interpreted high level programming language. It is often classified as a
["scripting language"](https://en.wikipedia.org/wiki/Scripting_language) and ["scripting language"](https://en.wikipedia.org/wiki/Scripting_language) and
is considered similar to languages such as Perl, Tcl, or Ruby. The syntax is considered similar to languages such as Perl, Tcl, or Ruby. The syntax
of Python is loosely inspired by elements of C programming. of Python is loosely inspired by elements of C programming.
@@ -40,12 +40,12 @@ able to type `python` like this:
``` ```
bash $ python bash $ python
Python 3.8.1 (default, Feb 20 2020, 09:29:22) Python 3.8.1 (default, Feb 20 2020, 09:29:22)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin [Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information. Type "help", "copyright", "credits" or "license" for more information.
>>> print("hello world") >>> print("hello world")
hello world hello world
>>> >>>
``` ```
If you are new to using the shell or a terminal, you should probably If you are new to using the shell or a terminal, you should probably
@@ -187,5 +187,5 @@ exercise work. For example:
If you can't make this work, don't worry about it. The rest of this course If you can't make this work, don't worry about it. The rest of this course
has nothing to do with parsing XML. has nothing to do with parsing XML.
[Contents](../Contents) \| [Next (1.2 A First Program)](02_Hello_world) [Contents](../Contents.md) \| [Next (1.2 A First Program)](02_Hello_world.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (1.1 Python)](01_Python) \| [Next (1.3 Numbers)](03_Numbers) [Contents](../Contents.md) \| [Previous (1.1 Python)](01_Python.md) \| [Next (1.3 Numbers)](03_Numbers.md)
# 1.2 A First Program # 1.2 A First Program
@@ -51,7 +51,7 @@ hello world
This so-called *read-eval-print-loop* (or REPL) is very useful for debugging and exploration. This so-called *read-eval-print-loop* (or REPL) is very useful for debugging and exploration.
**STOP**: If you can't figure out how to interact with Python, stop what you're doing **STOP**: If you can't figure out how to interact with Python, stop what you're doing
and figure out how to do it. If you're using an IDE, it might be hidden behind a and figure out how to do it. If you're using an IDE, it might be hidden behind a
menu option or other window. Many parts of this course assume that you can menu option or other window. Many parts of this course assume that you can
interact with the interpreter. interact with the interpreter.
@@ -63,7 +63,7 @@ Let's take a closer look at the elements of the REPL:
The `...` prompt may or may not be shown depending on your environment. For this course, The `...` prompt may or may not be shown depending on your environment. For this course,
it is shown as blanks to make it easier to cut/paste code samples. it is shown as blanks to make it easier to cut/paste code samples.
The underscore `_` holds the last result. The underscore `_` holds the last result.
```python ```python
>>> 37 * 42 >>> 37 * 42
@@ -109,7 +109,7 @@ C:\SomeFolder>c:\python36\python hello.py
hello world hello world
``` ```
Note: On Windows, you may need to specify a full path to the Python interpreter such as `c:\python36\python`. Note: On Windows, you may need to specify a full path to the Python interpreter such as `c:\python36\python`.
However, if Python is installed in its usual way, you might be able to just type the name of the program However, if Python is installed in its usual way, you might be able to just type the name of the program
such as `hello.py`. such as `hello.py`.
@@ -265,7 +265,7 @@ Indentation groups the following statements together as the operations that repe
num_bills = num_bills * 2 num_bills = num_bills * 2
``` ```
Because the `print()` statement at the end is not indented, it Because the `print()` statement at the end is not indented, it
does not belong to the loop. The empty line is just for does not belong to the loop. The empty line is just for
readability. It does not affect the execution. readability. It does not affect the execution.
@@ -275,7 +275,7 @@ readability. It does not affect the execution.
* Use 4 spaces per level. * Use 4 spaces per level.
* Use a Python-aware editor. * Use a Python-aware editor.
Python's only requirement is that indentation within the same block Python's only requirement is that indentation within the same block
be consistent. For example, this is an error: be consistent. For example, this is an error:
```python ```python
@@ -464,7 +464,7 @@ NameError: name 'days' is not defined
Reading error messages is an important part of Python code. If your program Reading error messages is an important part of Python code. If your program
crashes, the very last line of the traceback message is the actual reason why the crashes, the very last line of the traceback message is the actual reason why the
the program crashed. Above that, you should see a fragment of source code and then the program crashed. Above that, you should see a fragment of source code and then
an identifying filename and line number. an identifying filename and line number.
* Which line is the error? * Which line is the error?
* What is the error? * What is the error?
@@ -472,4 +472,4 @@ an identifying filename and line number.
* Run the program successfully * Run the program successfully
[Contents](../Contents) \| [Previous (1.1 Python)](01_Python) \| [Next (1.3 Numbers)](03_Numbers) [Contents](../Contents.md) \| [Previous (1.1 Python)](01_Python.md) \| [Next (1.3 Numbers)](03_Numbers.md)

View File

@@ -1,6 +1,6 @@
[Contents](../Contents) \| [Previous (1.2 A First Program)](02_Hello_world) \| [Next (1.4 Strings)](04_Strings) [Contents](../Contents.md) \| [Previous (1.2 A First Program)](02_Hello_world.md) \| [Next (1.4 Strings)](04_Strings.md)
# 1.3 Numbers # 1.3 Numbers
This section discusses mathematical calculations. This section discusses mathematical calculations.
@@ -55,7 +55,7 @@ x / y Divide (produces a float)
x // y Floor Divide (produces an integer) x // y Floor Divide (produces an integer)
x % y Modulo (remainder) x % y Modulo (remainder)
x ** y Power x ** y Power
x << n Bit shift left x << n Bit shift left
x >> n Bit shift right x >> n Bit shift right
x & y Bit-wise AND x & y Bit-wise AND
x | y Bit-wise OR x | y Bit-wise OR
@@ -170,7 +170,7 @@ Try it out.
## Exercises ## Exercises
Reminder: These exercises assume you are working in the `practical-python/Work` directory. Look Reminder: These exercises assume you are working in the `practical-python/Work` directory. Look
for the file `mortgage.py`. for the file `mortgage.py`.
### Exercise 1.7: Dave's mortgage ### Exercise 1.7: Dave's mortgage
@@ -224,7 +224,7 @@ How much will Dave pay if he pays an extra $1000/month for 4 years starting in y
### Exercise 1.10: Making a table ### Exercise 1.10: Making a table
Modify the program to print out a table showing the month, total paid so far, and the remaining principal. Modify the program to print out a table showing the month, total paid so far, and the remaining principal.
The output should look something like this: The output should look something like this:
```bash ```bash
@@ -264,4 +264,4 @@ True
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (1.2 A First Program)](02_Hello_world) \| [Next (1.4 Strings)](04_Strings) [Contents](../Contents.md) \| [Previous (1.2 A First Program)](02_Hello_world.md) \| [Next (1.4 Strings)](04_Strings.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (1.3 Numbers)](03_Numbers) \| [Next (1.5 Lists)](05_Lists) [Contents](../Contents.md) \| [Previous (1.3 Numbers)](03_Numbers.md) \| [Next (1.5 Lists)](05_Lists.md)
# 1.4 Strings # 1.4 Strings
@@ -299,7 +299,7 @@ Verify this by trying to change the first character of `symbols` to a lower-case
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment TypeError: 'str' object does not support item assignment
>>> >>>
``` ```
### Exercise 1.14: String concatenation ### Exercise 1.14: String concatenation
@@ -408,10 +408,10 @@ To do that, use an f-string. For example:
>>> price = 91.1 >>> price = 91.1
>>> f'{shares} shares of {name} at ${price:0.2f}' >>> f'{shares} shares of {name} at ${price:0.2f}'
'100 shares of IBM at $91.10' '100 shares of IBM at $91.10'
>>> >>>
``` ```
Modify the `mortgage.py` program from [Exercise 1.10](03_Numbers) to create its output using f-strings. Modify the `mortgage.py` program from [Exercise 1.10](03_Numbers.md) to create its output using f-strings.
Try to make it so that output is nicely aligned. Try to make it so that output is nicely aligned.
@@ -419,7 +419,7 @@ Try to make it so that output is nicely aligned.
One limitation of the basic string operations is that they don't One limitation of the basic string operations is that they don't
support any kind of advanced pattern matching. For that, you support any kind of advanced pattern matching. For that, you
need to turn to Python's `re` module and regular expressions. need to turn to Python's `re` module and regular expressions.
Regular expression handling is a big topic, but here is a short Regular expression handling is a big topic, but here is a short
example: example:
@@ -485,4 +485,4 @@ upper(...)
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (1.3 Numbers)](03_Numbers) \| [Next (1.5 Lists)](05_Lists) [Contents](../Contents.md) \| [Previous (1.3 Numbers)](03_Numbers.md) \| [Next (1.5 Lists)](05_Lists.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (1.4 Strings)](04_Strings) \| [Next (1.6 Files)](06_Files) [Contents](../Contents.md) \| [Previous (1.4 Strings)](04_Strings.md) \| [Next (1.6 Files)](06_Files.md)
# 1.5 Lists # 1.5 Lists
@@ -98,7 +98,7 @@ for name in names:
This is similar to a `foreach` statement from other programming languages. This is similar to a `foreach` statement from other programming languages.
To find the position of something quickly, use `index()`. To find the position of something quickly, use `index()`.
```python ```python
names = ['Elwood','Jake','Curtis'] names = ['Elwood','Jake','Curtis']
@@ -267,7 +267,7 @@ Use the `append()` method to add the symbol `'RHT'` to end of `symlist`.
>>> # append 'RHT' >>> # append 'RHT'
>>> symlist >>> symlist
['HPQ', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT'] ['HPQ', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT']
>>> >>>
``` ```
Use the `insert()` method to insert the symbol `'AA'` as the second item in the list. Use the `insert()` method to insert the symbol `'AA'` as the second item in the list.
@@ -411,4 +411,4 @@ example, a list that consists entirely of numbers or a list of text
strings. Mixing different kinds of data together in the same list is strings. Mixing different kinds of data together in the same list is
often a good way to make your head explode so it's best avoided. often a good way to make your head explode so it's best avoided.
[Contents](../Contents) \| [Previous (1.4 Strings)](04_Strings) \| [Next (1.6 Files)](06_Files) [Contents](../Contents.md) \| [Previous (1.4 Strings)](04_Strings.md) \| [Next (1.6 Files)](06_Files.md)

View File

@@ -1,8 +1,8 @@
[Contents](../Contents) \| [Previous (1.5 Lists)](05_Lists) \| [Next (1.7 Functions)](07_Functions) [Contents](../Contents.md) \| [Previous (1.5 Lists)](05_Lists.md) \| [Next (1.7 Functions)](07_Functions.md)
# 1.6 File Management # 1.6 File Management
Most programs need to read input from somewhere. This section discusses file access. Most programs need to read input from somewhere. This section discusses file access.
### File Input and Output ### File Input and Output
@@ -63,7 +63,7 @@ Read a file line-by-line by iterating.
```python ```python
with open(filename, 'rt') as file: with open(filename, 'rt') as file:
for line in file: for line in file:
# Process the line # Process the line
``` ```
### Common Idioms for Writing to a File ### Common Idioms for Writing to a File
@@ -168,7 +168,7 @@ of column headers).
>>> >>>
``` ```
`next()` returns the next line of text in the file. If you were to call it repeatedly, you would get successive lines. `next()` returns the next line of text in the file. If you were to call it repeatedly, you would get successive lines.
However, just so you know, the `for` loop already uses `next()` to obtain its data. However, just so you know, the `for` loop already uses `next()` to obtain its data.
Thus, you normally wouldnt call it directly unless youre trying to explicitly skip or read a single line as shown. Thus, you normally wouldnt call it directly unless youre trying to explicitly skip or read a single line as shown.
@@ -234,7 +234,7 @@ Data scientists are quick to point out that libraries like
[Pandas](https://pandas.pydata.org) already have a function for [Pandas](https://pandas.pydata.org) already have a function for
reading CSV files. This is true--and it works pretty well. reading CSV files. This is true--and it works pretty well.
However, this is not a course on learning Pandas. Reading files However, this is not a course on learning Pandas. Reading files
is a more general problem than the specifics of CSV files. is a more general problem than the specifics of CSV files.
The main reason we're working with a CSV file is that it's a The main reason we're working with a CSV file is that it's a
familiar format to most coders and it's relatively easy to work with familiar format to most coders and it's relatively easy to work with
directly--illustrating many Python features in the process. directly--illustrating many Python features in the process.
@@ -242,4 +242,4 @@ So, by all means use Pandas when you go back to work. For the
rest of this course however, we're going to stick with standard rest of this course however, we're going to stick with standard
Python functionality. Python functionality.
[Contents](../Contents) \| [Previous (1.5 Lists)](05_Lists) \| [Next (1.7 Functions)](07_Functions) [Contents](../Contents.md) \| [Previous (1.5 Lists)](05_Lists.md) \| [Next (1.7 Functions)](07_Functions.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (1.6 Files)](06_Files) \| [Next (2.0 Working with Data)](../02_Working_with_data/00_Overview) [Contents](../Contents.md) \| [Previous (1.6 Files)](06_Files.md) \| [Next (2.0 Working with Data)](../02_Working_with_data/00_Overview.md)
# 1.7 Functions # 1.7 Functions
@@ -41,7 +41,7 @@ import math
x = math.sqrt(10) x = math.sqrt(10)
import urllib.request import urllib.request
u = urllib.request.urlopen('http://www.python.org/') u = urllib.request.urlopen('http://www.python.org/')
data = u.read() data = u.read()
``` ```
@@ -49,7 +49,7 @@ We will cover libraries and modules in more detail later.
### Errors and exceptions ### Errors and exceptions
Functions report errors as exceptions. An exception causes a function to abort and may Functions report errors as exceptions. An exception causes a function to abort and may
cause your entire program to stop if unhandled. cause your entire program to stop if unhandled.
Try this in your python REPL. Try this in your python REPL.
@@ -130,7 +130,7 @@ Try typing a command such as `help(greeting)` to see it displayed.
### Exercise 1.30: Turning a script into a function ### Exercise 1.30: Turning a script into a function
Take the code you wrote for the `pcost.py` program in [Exercise 1.27](06_Files) Take the code you wrote for the `pcost.py` program in [Exercise 1.27](06_Files.md)
and turn it into a function `portfolio_cost(filename)`. This and turn it into a function `portfolio_cost(filename)`. This
function takes a filename as input, reads the portfolio data in that function takes a filename as input, reads the portfolio data in that
file, and returns the total cost of the portfolio as a float. file, and returns the total cost of the portfolio as a float.
@@ -278,4 +278,4 @@ Total cost: 44671.15
bash % bash %
``` ```
[Contents](../Contents) \| [Previous (1.6 Files)](06_Files) \| [Next (2.0 Working with Data)](../02_Working_with_data/00_Overview) [Contents](../Contents.md) \| [Previous (1.6 Files)](06_Files.md) \| [Next (2.0 Working with Data)](../02_Working_with_data/00_Overview.md)

View File

@@ -6,12 +6,12 @@ lists, sets, and dictionaries and discusses common data handling
idioms. The last part of this section dives a little deeper idioms. The last part of this section dives a little deeper
into Python's underlying object model. into Python's underlying object model.
* [2.1 Datatypes and Data Structures](01_Datatypes) * [2.1 Datatypes and Data Structures](01_Datatypes.md)
* [2.2 Containers](02_Containers) * [2.2 Containers](02_Containers.md)
* [2.3 Formatted Output](03_Formatting) * [2.3 Formatted Output](03_Formatting.md)
* [2.4 Sequences](04_Sequences) * [2.4 Sequences](04_Sequences.md)
* [2.5 Collections module](05_Collections) * [2.5 Collections module](05_Collections.md)
* [2.6 List comprehensions](06_List_comprehension) * [2.6 List comprehensions](06_List_comprehension.md)
* [2.7 Object model](07_Objects) * [2.7 Object model](07_Objects.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (1.6 Files)](../01_Introduction/06_Files) \| [Next (2.2 Containers)](02_Containers) [Contents](../Contents.md) \| [Previous (1.6 Files)](../01_Introduction/06_Files.md) \| [Next (2.2 Containers)](02_Containers)
# 2.1 Datatypes and Data structures # 2.1 Datatypes and Data structures
@@ -242,7 +242,7 @@ shares and the price:
``` ```
Is math broken in Python? Whats the deal with the answer of Is math broken in Python? Whats the deal with the answer of
3220.0000000000005? 3220.0000000000005?
This is an artifact of the floating point hardware on your computer This is an artifact of the floating point hardware on your computer
only being able to accurately represent decimals in Base-2, not only being able to accurately represent decimals in Base-2, not
@@ -446,4 +446,4 @@ dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 20
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (1.6 Files)](../01_Introduction/06_Files) \| [Next (2.2 Containers)](02_Containers) [Contents](../Contents.md) \| [Previous (1.6 Files)](../01_Introduction/06_Files.md) \| [Next (2.2 Containers)](02_Containers)

View File

@@ -1,8 +1,8 @@
[Contents](../Contents) \| [Previous (2.1 Datatypes)](01_Datatypes) \| [Next (2.3 Formatting)](03_Formatting) [Contents](../Contents.md) \| [Previous (2.1 Datatypes)](01_Datatypes) \| [Next (2.3 Formatting)](03_Formatting)
# 2.2 Containers # 2.2 Containers
This section discusses lists, dictionaries, and sets. This section discusses lists, dictionaries, and sets.
### Overview ### Overview
@@ -205,7 +205,7 @@ for the rest of this course. Do your work in the file `Work/report.py`.
### Exercise 2.4: A list of tuples ### Exercise 2.4: A list of tuples
The file `Data/portfolio.csv` contains a list of stocks in a The file `Data/portfolio.csv` contains a list of stocks in a
portfolio. In [Exercise 1.30](../01_Introduction/07_Functions), you portfolio. In [Exercise 1.30](../01_Introduction/07_Functions.md), you
wrote a function `portfolio_cost(filename)` that read this file and wrote a function `portfolio_cost(filename)` that read this file and
performed a simple calculation. performed a simple calculation.
@@ -442,5 +442,5 @@ should take the list of stocks in Exercise 2.5 and the dictionary of
prices in Exercise 2.6 and computes the current value of the portfolio prices in Exercise 2.6 and computes the current value of the portfolio
along with the gain/loss. along with the gain/loss.
[Contents](../Contents) \| [Previous (2.1 Datatypes)](01_Datatypes) \| [Next (2.3 Formatting)](03_Formatting) [Contents](../Contents.md) \| [Previous (2.1 Datatypes)](01_Datatypes) \| [Next (2.3 Formatting)](03_Formatting)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (2.2 Containers)](02_Containers) \| [Next (2.4 Sequences)](04_Sequences) [Contents](../Contents.md) \| [Previous (2.2 Containers)](02_Containers) \| [Next (2.4 Sequences)](04_Sequences)
# 2.3 Formatting # 2.3 Formatting
@@ -77,7 +77,7 @@ You can use the `format_map()` method to apply string formatting to a dictionary
``` ```
It uses the same codes as `f-strings` but takes the values from the It uses the same codes as `f-strings` but takes the values from the
supplied dictionary. supplied dictionary.
### format() method ### format() method
@@ -92,7 +92,7 @@ keyword arguments.
>>> >>>
``` ```
Frankly, `format()` is a bit verbose. I prefer f-strings. Frankly, `format()` is a bit verbose. I prefer f-strings.
### C-Style Formatting ### C-Style Formatting
@@ -299,4 +299,4 @@ How would you modify your code so that the price includes the currency symbol ($
IBM 100 $106.28 35.84 IBM 100 $106.28 35.84
``` ```
[Contents](../Contents) \| [Previous (2.2 Containers)](02_Containers) \| [Next (2.4 Sequences)](04_Sequences) [Contents](../Contents.md) \| [Previous (2.2 Containers)](02_Containers) \| [Next (2.4 Sequences)](04_Sequences)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (2.3 Formatting)](03_Formatting) \| [Next (2.5 Collections)](05_Collections) [Contents](../Contents.md) \| [Previous (2.3 Formatting)](03_Formatting) \| [Next (2.5 Collections)](05_Collections)
# 2.4 Sequences # 2.4 Sequences
@@ -546,4 +546,4 @@ Also, be aware that `zip()` stops once the shortest input sequence is exhausted.
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (2.3 Formatting)](03_Formatting) \| [Next (2.5 Collections)](05_Collections) [Contents](../Contents.md) \| [Previous (2.3 Formatting)](03_Formatting) \| [Next (2.5 Collections)](05_Collections)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (2.4 Sequences)](04_Sequences) \| [Next (2.6 List Comprehensions)](06_List_comprehension) [Contents](../Contents.md) \| [Previous (2.4 Sequences)](04_Sequences) \| [Next (2.6 List Comprehensions)](06_List_comprehension)
# 2.5 collections module # 2.5 collections module
@@ -168,4 +168,4 @@ in all of Python. In fact, we could do an extended tutorial on just
that. However, doing so now would also be a distraction. For now, that. However, doing so now would also be a distraction. For now,
put `collections` on your list of bedtime reading for later. put `collections` on your list of bedtime reading for later.
[Contents](../Contents) \| [Previous (2.4 Sequences)](04_Sequences) \| [Next (2.6 List Comprehensions)](06_List_comprehension) [Contents](../Contents.md) \| [Previous (2.4 Sequences)](04_Sequences) \| [Next (2.6 List Comprehensions)](06_List_comprehension)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (2.5 Collections)](05_Collections) \| [Next (2.7 Object Model)](07_Objects) [Contents](../Contents.md) \| [Previous (2.5 Collections)](05_Collections) \| [Next (2.7 Object Model)](07_Objects)
# 2.6 List Comprehensions # 2.6 List Comprehensions
@@ -310,7 +310,7 @@ of the file:
Oh my, you just reduced much of the `read_portfolio()` function to a single statement. Oh my, you just reduced much of the `read_portfolio()` function to a single statement.
### Commentary ### Commentary
List comprehensions are commonly used in Python as an efficient means List comprehensions are commonly used in Python as an efficient means
for transforming, filtering, or collecting data. Due to the syntax, for transforming, filtering, or collecting data. Due to the syntax,
@@ -326,4 +326,4 @@ extraction, and so forth. Becoming a guru master of list
comprehensions can substantially reduce the time spent devising a comprehensions can substantially reduce the time spent devising a
solution. Also, don't forget about the `collections` module. solution. Also, don't forget about the `collections` module.
[Contents](../Contents) \| [Previous (2.5 Collections)](05_Collections) \| [Next (2.7 Object Model)](07_Objects) [Contents](../Contents.md) \| [Previous (2.5 Collections)](05_Collections) \| [Next (2.7 Object Model)](07_Objects)

View File

@@ -1,8 +1,8 @@
[Contents](../Contents) \| [Previous (2.6 List Comprehensions)](06_List_comprehension) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview) [Contents](../Contents.md) \| [Previous (2.6 List Comprehensions)](06_List_comprehension) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview)
# 2.7 Objects # 2.7 Objects
This section introduces more details about Python's internal object model and This section introduces more details about Python's internal object model and
discusses some matters related to memory management, copying, and type checking. discusses some matters related to memory management, copying, and type checking.
### Assignment ### Assignment
@@ -451,4 +451,4 @@ Bonus: How would you modify this example to additionally parse the
Spend some time to ponder what youve done in this exercise. Well Spend some time to ponder what youve done in this exercise. Well
revisit these ideas a little later. revisit these ideas a little later.
[Contents](../Contents) \| [Previous (2.6 List Comprehensions)](06_List_comprehension) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview) [Contents](../Contents.md) \| [Previous (2.6 List Comprehensions)](06_List_comprehension) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview)

View File

@@ -7,11 +7,11 @@ and introduces modules. By the end you should be able to write programs
that are subdivided into functions across multiple files. We'll also give that are subdivided into functions across multiple files. We'll also give
some useful code templates for writing more useful scripts. some useful code templates for writing more useful scripts.
* [3.1 Functions and Script Writing](01_Script) * [3.1 Functions and Script Writing](01_Script.md)
* [3.2 More Detail on Functions](02_More_functions) * [3.2 More Detail on Functions](02_More_functions.md)
* [3.3 Exception Handling](03_Error_checking) * [3.3 Exception Handling](03_Error_checking.md)
* [3.4 Modules](04_Modules) * [3.4 Modules](04_Modules.md)
* [3.5 Main module](05_Main_module) * [3.5 Main module](05_Main_module.md)
* [3.6 Design Discussion about Embracing Flexibilty](06_Design_discussion) * [3.6 Design Discussion about Embracing Flexibilty](06_Design_discussion.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (2.7 Object Model)](../02_Working_with_data/07_Objects) \| [Next (3.2 More on Functions)](02_More_functions) [Contents](../Contents.md) \| [Previous (2.7 Object Model)](../02_Working_with_data/07_Objects) \| [Next (3.2 More on Functions)](02_More_functions)
# 3.1 Scripting # 3.1 Scripting
@@ -143,7 +143,7 @@ spam(42) # Code that uses the functions appears at the end
Later functions build upon earlier functions. Again, this is only Later functions build upon earlier functions. Again, this is only
a point of style. The only thing that matters in the above program a point of style. The only thing that matters in the above program
is that the call to `spam(42)` go last. is that the call to `spam(42)` go last.
### Function Design ### Function Design
@@ -153,7 +153,7 @@ and mysterious side-effects. Your main goals: *Modularity* and *Predictability*
### Doc Strings ### Doc Strings
It's good practice to include documentation in the form of a It's good practice to include documentation in the form of a
doc-string. Doc-strings are strings written immediately after the doc-string. Doc-strings are strings written immediately after the
name of the function. They feed `help()`, IDEs and other tools. name of the function. They feed `help()`, IDEs and other tools.
@@ -194,7 +194,7 @@ def read_prices(filename: str) -> dict:
The hints do nothing operationally. They are purely informational. The hints do nothing operationally. They are purely informational.
However, they may be used by IDEs, code checkers, and other tools However, they may be used by IDEs, code checkers, and other tools
to do more. to do more.
## Exercises ## Exercises
@@ -299,4 +299,4 @@ you can. At some point, that script is going to grow and you'll wish
you had a bit more organization. Also, a little known fact is that Python you had a bit more organization. Also, a little known fact is that Python
runs a bit faster if you use functions. runs a bit faster if you use functions.
[Contents](../Contents) \| [Previous (2.7 Object Model)](../02_Working_with_data/07_Objects) \| [Next (3.2 More on Functions)](02_More_functions) [Contents](../Contents.md) \| [Previous (2.7 Object Model)](../02_Working_with_data/07_Objects) \| [Next (3.2 More on Functions)](02_More_functions)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (3.1 Scripting)](01_Script) \| [Next (3.3 Error Checking)](03_Error_checking) [Contents](../Contents.md) \| [Previous (3.1 Scripting)](01_Script) \| [Next (3.3 Error Checking)](03_Error_checking)
# 3.2 More on Functions # 3.2 More on Functions
@@ -273,7 +273,7 @@ Start this exercise by creating a new file called
### Exercise 3.3: Reading CSV Files ### Exercise 3.3: Reading CSV Files
To start, lets just focus on the problem of reading a CSV file into a To start, lets just focus on the problem of reading a CSV file into a
list of dictionaries. In the file `fileparse.py`, define a list of dictionaries. In the file `fileparse.py`, define a
function that looks like this: function that looks like this:
```python ```python
@@ -338,7 +338,7 @@ follows:
>>> >>>
``` ```
An example of a column selector was given in [Exercise 2.23](../02_Working_with_data/06_List_comprehension). An example of a column selector was given in [Exercise 2.23](../02_Working_with_data/06_List_comprehension).
However, heres one way to do it: However, heres one way to do it:
```python ```python
@@ -431,7 +431,7 @@ type-conversions to be applied to the returned data. For example:
>>> >>>
``` ```
You already explored this in [Exercise 2.24](../02_Working_with_data/07_Objects). You already explored this in [Exercise 2.24](../02_Working_with_data/07_Objects).
You'll need to insert the following fragment of code into your solution: You'll need to insert the following fragment of code into your solution:
```python ```python
@@ -513,4 +513,4 @@ select out columns of interest, perform type conversions, without
having to worry too much about the inner workings of files or the having to worry too much about the inner workings of files or the
`csv` module. `csv` module.
[Contents](../Contents) \| [Previous (3.1 Scripting)](01_Script) \| [Next (3.3 Error Checking)](03_Error_checking) [Contents](../Contents.md) \| [Previous (3.1 Scripting)](01_Script) \| [Next (3.3 Error Checking)](03_Error_checking)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (3.2 More on Functions)](02_More_functions) \| [Next (3.4 Modules)](04_Modules) [Contents](../Contents.md) \| [Previous (3.2 More on Functions)](02_More_functions) \| [Next (3.4 Modules)](04_Modules)
# 3.3 Error Checking # 3.3 Error Checking
@@ -241,7 +241,7 @@ except Exception as e:
It reports a specific reason for failure. It is almost always a good It reports a specific reason for failure. It is almost always a good
idea to have some mechanism for viewing/reporting errors when you idea to have some mechanism for viewing/reporting errors when you
write code that catches all possible exceptions. write code that catches all possible exceptions.
In general though, it's better to catch the error as narrowly as is In general though, it's better to catch the error as narrowly as is
reasonable. Only catch the errors you can actually handle. Let reasonable. Only catch the errors you can actually handle. Let
@@ -402,4 +402,4 @@ most programs. As a general rule, you shouldnt silently ignore
errors. Instead, its better to report problems and to give the user errors. Instead, its better to report problems and to give the user
an option to the silence the error message if they choose to do so. an option to the silence the error message if they choose to do so.
[Contents](../Contents) \| [Previous (3.2 More on Functions)](02_More_functions) \| [Next (3.4 Modules)](04_Modules) [Contents](../Contents.md) \| [Previous (3.2 More on Functions)](02_More_functions) \| [Next (3.4 Modules)](04_Modules)

View File

@@ -1,9 +1,9 @@
[Contents](../Contents) \| [Previous (3.3 Error Checking)](03_Error_checking) \| [Next (3.5 Main Module)](05_Main_module) [Contents](../Contents.md) \| [Previous (3.3 Error Checking)](03_Error_checking) \| [Next (3.5 Main Module)](05_Main_module)
# 3.4 Modules # 3.4 Modules
This section introduces the concept of modules and working with functions that span This section introduces the concept of modules and working with functions that span
multiple files. multiple files.
### Modules and import ### Modules and import
@@ -164,7 +164,7 @@ Each module loads and executes only *once*.
changing the source code for a module. Because of the module cache `sys.modules`, changing the source code for a module. Because of the module cache `sys.modules`,
repeated imports always return the previously loaded module--even if a change repeated imports always return the previously loaded module--even if a change
was made. The safest way to load modified code into Python is to quit and restart was made. The safest way to load modified code into Python is to quit and restart
the interpreter. the interpreter.
### Locating Modules ### Locating Modules
@@ -214,7 +214,7 @@ not readily accessible from the current working directory.
For this exercise involving modules, it is critically important to For this exercise involving modules, it is critically important to
make sure you are running Python in a proper environment. Modules are make sure you are running Python in a proper environment. Modules are
usually when programmers encounter problems with the current working usually when programmers encounter problems with the current working
directory or with Python's path settings. For this course, it is directory or with Python's path settings. For this course, it is
assumed that you're writing all of your code in the `Work/` directory. assumed that you're writing all of your code in the `Work/` directory.
For best results, you should make sure you're also in that directory For best results, you should make sure you're also in that directory
when you launch the interpreter. If not, you need to make sure when you launch the interpreter. If not, you need to make sure
@@ -338,4 +338,4 @@ also contains `read_portfolio()` and `read_prices()` functions. And
finally, `pcost.py` which computes the portfolio cost, but makes use finally, `pcost.py` which computes the portfolio cost, but makes use
of the `read_portfolio()` function written for the `report.py` program. of the `read_portfolio()` function written for the `report.py` program.
[Contents](../Contents) \| [Previous (3.3 Error Checking)](03_Error_checking) \| [Next (3.5 Main Module)](05_Main_module) [Contents](../Contents.md) \| [Previous (3.3 Error Checking)](03_Error_checking) \| [Next (3.5 Main Module)](05_Main_module)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (3.4 Modules)](04_Modules) \| [Next (3.6 Design Discussion)](06_Design_discussion) [Contents](../Contents.md) \| [Previous (3.4 Modules)](04_Modules) \| [Next (3.6 Design Discussion)](06_Design_discussion)
# 3.5 Main Module # 3.5 Main Module
@@ -303,4 +303,4 @@ bash $ python3 pcost.py Data/portfolio.csv
Total cost: 44671.15 Total cost: 44671.15
``` ```
[Contents](../Contents) \| [Previous (3.4 Modules)](04_Modules) \| [Next (3.6 Design Discussion)](06_Design_discussion) [Contents](../Contents.md) \| [Previous (3.4 Modules)](04_Modules) \| [Next (3.6 Design Discussion)](06_Design_discussion)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (3.5 Main module)](05_Main_module) \| [Next (4 Classes)](../04_Classes_objects/00_Overview) [Contents](../Contents.md) \| [Previous (3.5 Main module)](05_Main_module) \| [Next (4 Classes)](../04_Classes_objects/00_Overview)
# 3.6 Design Discussion # 3.6 Design Discussion
@@ -91,7 +91,7 @@ Don't restrict your options. With great flexibility comes great power.
### Exercise 3.17: From filenames to file-like objects ### Exercise 3.17: From filenames to file-like objects
You've now created a file `fileparse.py` that contained a You've now created a file `fileparse.py` that contained a
function `parse_csv()`. The function worked like this: function `parse_csv()`. The function worked like this:
```python ```python
@@ -100,7 +100,7 @@ function `parse_csv()`. The function worked like this:
>>> >>>
``` ```
Right now, the function expects to be passed a filename. However, you Right now, the function expects to be passed a filename. However, you
can make the code more flexible. Modify the function so that it works can make the code more flexible. Modify the function so that it works
with any file-like/iterable object. For example: with any file-like/iterable object. For example:
@@ -134,4 +134,4 @@ Fix the `read_portfolio()` and `read_prices()` functions in the
Afterwards, your `report.py` and `pcost.py` programs should work Afterwards, your `report.py` and `pcost.py` programs should work
the same way they always did. the same way they always did.
[Contents](../Contents) \| [Previous (3.5 Main module)](05_Main_module) \| [Next (4 Classes)](../04_Classes_objects/00_Overview) [Contents](../Contents.md) \| [Previous (3.5 Main module)](05_Main_module) \| [Next (4 Classes)](../04_Classes_objects/00_Overview)

View File

@@ -8,9 +8,9 @@ use to build extensible programs. Finally, we'll look at a few other
features of classes including special methods, dynamic attribute lookup, features of classes including special methods, dynamic attribute lookup,
and defining new exceptions. and defining new exceptions.
* [4.1 Introducing Classes](01_Class) * [4.1 Introducing Classes](01_Class.md)
* [4.2 Inheritance](02_Inheritance) * [4.2 Inheritance](02_Inheritance.md)
* [4.3 Special Methods](03_Special_methods) * [4.3 Special Methods](03_Special_methods.md)
* [4.4 Defining new Exception](04_Defining_exceptions) * [4.4 Defining new Exception](04_Defining_exceptions.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (3.6 Design discussion)](../03_Program_organization/06_Design_discussion) \| [Next (4.2 Inheritance)](02_Inheritance) [Contents](../Contents.md) \| [Previous (3.6 Design discussion)](../03_Program_organization/06_Design_discussion) \| [Next (4.2 Inheritance)](02_Inheritance)
# 4.1 Classes # 4.1 Classes
@@ -256,8 +256,8 @@ dictionaries. Then compute the total cost:
... ...
>>> portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts] >>> portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts]
>>> portfolio >>> portfolio
[<stock.Stock object at 0x10c9e2128>, <stock.Stock object at 0x10c9e2048>, <stock.Stock object at 0x10c9e2080>, [<stock.Stock object at 0x10c9e2128>, <stock.Stock object at 0x10c9e2048>, <stock.Stock object at 0x10c9e2080>,
<stock.Stock object at 0x10c9e25f8>, <stock.Stock object at 0x10c9e2630>, <stock.Stock object at 0x10ca6f748>, <stock.Stock object at 0x10c9e25f8>, <stock.Stock object at 0x10c9e2630>, <stock.Stock object at 0x10ca6f748>,
<stock.Stock object at 0x10ca6f7b8>] <stock.Stock object at 0x10ca6f7b8>]
>>> sum([s.cost() for s in portfolio]) >>> sum([s.cost() for s in portfolio])
44671.15 44671.15
@@ -283,16 +283,16 @@ You should be able to run your functions the same as before:
44671.15 44671.15
>>> import report >>> import report
>>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv') >>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv')
Name Shares Price Change Name Shares Price Change
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
AA 100 9.22 -22.98 AA 100 9.22 -22.98
IBM 50 106.28 15.18 IBM 50 106.28 15.18
CAT 150 35.46 -47.98 CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34 MSFT 200 20.89 -30.34
GE 95 13.48 -26.89 GE 95 13.48 -26.89
MSFT 50 20.89 -44.21 MSFT 50 20.89 -44.21
IBM 100 106.28 35.84 IBM 100 106.28 35.84
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (3.6 Design discussion)](../03_Program_organization/06_Design_discussion) \| [Next (4.2 Inheritance)](02_Inheritance) [Contents](../Contents.md) \| [Previous (3.6 Design discussion)](../03_Program_organization/06_Design_discussion) \| [Next (4.2 Inheritance)](02_Inheritance)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (4.1 Classes)](01_Class) \| [Next (4.3 Special methods)](03_Special_methods) [Contents](../Contents.md) \| [Previous (4.1 Classes)](01_Class) \| [Next (4.3 Special methods)](03_Special_methods)
# 4.2 Inheritance # 4.2 Inheritance
@@ -158,7 +158,7 @@ class Rectangle(Shape):
``` ```
Think of a logical hierarchy or taxonomy. However, a more common (and Think of a logical hierarchy or taxonomy. However, a more common (and
practical) usage is related to making reusable or extensible code. practical) usage is related to making reusable or extensible code.
For example, a framework might define a base class and instruct you For example, a framework might define a base class and instruct you
to customize it. to customize it.
@@ -170,7 +170,7 @@ class CustomHandler(TCPHandler):
``` ```
The base class contains some general purpose code. The base class contains some general purpose code.
Your class inherits and customized specific parts. Your class inherits and customized specific parts.
### "is a" relationship ### "is a" relationship
@@ -193,7 +193,7 @@ True
>>> >>>
``` ```
*Important: Ideally, any code that worked with instances of the parent *Important: Ideally, any code that worked with instances of the parent
class will also work with instances of the child class.* class will also work with instances of the child class.*
### `object` base class ### `object` base class
@@ -235,7 +235,7 @@ going to utilize multiple inheritance further in this course.
A major use of inheritance is in writing code that's meant to be A major use of inheritance is in writing code that's meant to be
extended or customized in various ways--especially in libraries or extended or customized in various ways--especially in libraries or
frameworks. To illustrate, consider the `print_report()` function frameworks. To illustrate, consider the `print_report()` function
in your `report.py` program. It should look something like this: in your `report.py` program. It should look something like this:
```python ```python
@@ -298,7 +298,7 @@ class TableFormatter:
raise NotImplementedError() raise NotImplementedError()
``` ```
This class does nothing, but it serves as a kind of design specification for This class does nothing, but it serves as a kind of design specification for
additional classes that will be defined shortly. A class like this is additional classes that will be defined shortly. A class like this is
sometimes called an "abstract base class." sometimes called an "abstract base class."
@@ -334,7 +334,7 @@ def portfolio_report(portfoliofile, pricefile):
''' '''
Make a stock report given portfolio and price data files. Make a stock report given portfolio and price data files.
''' '''
# Read data files # Read data files
portfolio = read_portfolio(portfoliofile) portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile) prices = read_prices(pricefile)
@@ -355,7 +355,7 @@ Run this new code:
... crashes ... ... crashes ...
``` ```
It should immediately crash with a `NotImplementedError` exception. That's not It should immediately crash with a `NotImplementedError` exception. That's not
too exciting, but it's exactly what we expected. Continue to the next part. too exciting, but it's exactly what we expected. Continue to the next part.
### Exercise 4.6: Using Inheritance to Produce Different Output ### Exercise 4.6: Using Inheritance to Produce Different Output
@@ -392,7 +392,7 @@ def portfolio_report(portfoliofile, pricefile):
''' '''
Make a stock report given portfolio and price data files. Make a stock report given portfolio and price data files.
''' '''
# Read data files # Read data files
portfolio = read_portfolio(portfoliofile) portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile) prices = read_prices(pricefile)
@@ -446,7 +446,7 @@ def portfolio_report(portfoliofile, pricefile):
''' '''
Make a stock report given portfolio and price data files. Make a stock report given portfolio and price data files.
''' '''
# Read data files # Read data files
portfolio = read_portfolio(portfoliofile) portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile) prices = read_prices(pricefile)
@@ -494,7 +494,7 @@ Test your code by modifying the main program to create a
### Exercise 4.7: Polymorphism in Action ### Exercise 4.7: Polymorphism in Action
A major feature of object-oriented programming is that you can A major feature of object-oriented programming is that you can
plug an object into a program and it will work without having to plug an object into a program and it will work without having to
change any of the existing code. For example, if you wrote a program change any of the existing code. For example, if you wrote a program
that expected to use a `TableFormatter` object, it would work no that expected to use a `TableFormatter` object, it would work no
@@ -512,7 +512,7 @@ def portfolio_report(portfoliofile, pricefile, fmt='txt'):
''' '''
Make a stock report given portfolio and price data files. Make a stock report given portfolio and price data files.
''' '''
# Read data files # Read data files
portfolio = read_portfolio(portfoliofile) portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile) prices = read_prices(pricefile)
@@ -547,7 +547,7 @@ def portfolio_report(portfoliofile, pricefile, fmt='txt'):
''' '''
Make a stock report given portfolio and price data files. Make a stock report given portfolio and price data files.
''' '''
# Read data files # Read data files
portfolio = read_portfolio(portfoliofile) portfolio = read_portfolio(portfoliofile)
prices = read_prices(pricefile) prices = read_prices(pricefile)
@@ -568,15 +568,15 @@ an optional argument specifying the output format. For example:
```python ```python
>>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv', 'txt') >>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv', 'txt')
Name Shares Price Change Name Shares Price Change
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
AA 100 9.22 -22.98 AA 100 9.22 -22.98
IBM 50 106.28 15.18 IBM 50 106.28 15.18
CAT 150 35.46 -47.98 CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34 MSFT 200 20.89 -30.34
GE 95 13.48 -26.89 GE 95 13.48 -26.89
MSFT 50 20.89 -44.21 MSFT 50 20.89 -44.21
IBM 100 106.28 35.84 IBM 100 106.28 35.84
>>> >>>
``` ```
@@ -614,7 +614,7 @@ you can change the internal implementation to work in any way that you
want. You can write all-custom code. You can use someone's third want. You can write all-custom code. You can use someone's third
party package. You swap out one third-party package for a different party package. You swap out one third-party package for a different
package when you find a better one. It doesn't matter--none of package when you find a better one. It doesn't matter--none of
your application code will break as long as you preserve keep the your application code will break as long as you preserve keep the
interface. That's a powerful idea and it's one of the reasons why interface. That's a powerful idea and it's one of the reasons why
you might consider inheritance for something like this. you might consider inheritance for something like this.
@@ -624,4 +624,4 @@ on the topic of design patterns (although understanding what happened
in this exercise will take you pretty far in terms of using objects in in this exercise will take you pretty far in terms of using objects in
a practically useful way). a practically useful way).
[Contents](../Contents) \| [Previous (4.1 Classes)](01_Class) \| [Next (4.3 Special methods)](03_Special_methods) [Contents](../Contents.md) \| [Previous (4.1 Classes)](01_Class) \| [Next (4.3 Special methods)](03_Special_methods)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (4.2 Inheritance)](02_Inheritance) \| [Next (4.4 Exceptions)](04_Defining_exceptions) [Contents](../Contents.md) \| [Previous (4.2 Inheritance)](02_Inheritance) \| [Next (4.4 Exceptions)](04_Defining_exceptions)
# 4.3 Special Methods # 4.3 Special Methods
@@ -177,7 +177,7 @@ f.close # Oops, Didn't do anything at all. `f` still open.
``` ```
In both of these cases, the error is cause by forgetting to include the In both of these cases, the error is cause by forgetting to include the
trailing parentheses. For example, `s.cost()` or `f.close()`. trailing parentheses. For example, `s.cost()` or `f.close()`.
### Attribute Access ### Attribute Access
@@ -276,7 +276,7 @@ it should work:
>>> print_table(portfolio, ['name','shares','price'], formatter) >>> print_table(portfolio, ['name','shares','price'], formatter)
name shares price name shares price
---------- ---------- ---------- ---------- ---------- ----------
AA 100 32.2 AA 100 32.2
IBM 50 91.1 IBM 50 91.1
CAT 150 83.44 CAT 150 83.44
@@ -284,8 +284,8 @@ it should work:
GE 95 40.37 GE 95 40.37
MSFT 50 65.1 MSFT 50 65.1
IBM 100 70.44 IBM 100 70.44
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (4.2 Inheritance)](02_Inheritance) \| [Next (4.4 Exceptions)](04_Defining_exceptions) [Contents](../Contents.md) \| [Previous (4.2 Inheritance)](02_Inheritance) \| [Next (4.4 Exceptions)](04_Defining_exceptions)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview) [Contents](../Contents.md) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview)
# 4.4 Defining Exceptions # 4.4 Defining Exceptions
@@ -51,4 +51,4 @@ FormatError: Unknown table format xls
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview) [Contents](../Contents.md) \| [Previous (4.3 Special methods)](03_Special_methods) \| [Next (5 Object Model)](../05_Object_model/00_Overview)

View File

@@ -13,8 +13,8 @@ It's not necessary to worry about the inner details to be productive.
However, most Python coders have a basic awareness of how classes However, most Python coders have a basic awareness of how classes
work. So, that's why we're covering it. work. So, that's why we're covering it.
* [5.1 Dictionaries Revisited (Object Implementation)](01_Dicts_revisited) * [5.1 Dictionaries Revisited (Object Implementation)](01_Dicts_revisited.md)
* [5.2 Encapsulation Techniques](02_Classes_encapsulation) * [5.2 Encapsulation Techniques](02_Classes_encapsulation.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (4.4 Exceptions)](../04_Classes_objects/04_Defining_exceptions) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation) [Contents](../Contents.md) \| [Previous (4.4 Exceptions)](../04_Classes_objects/04_Defining_exceptions) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation)
# 5.1 Dictionaries Revisited # 5.1 Dictionaries Revisited
@@ -279,7 +279,7 @@ about class ordering.
* Children are always checked before parents * Children are always checked before parents
* Parents (if multiple) are always checked in the order listed. * Parents (if multiple) are always checked in the order listed.
The MRO is computed by sorting all of the classes in a hierarchy The MRO is computed by sorting all of the classes in a hierarchy
according to those rules. according to those rules.
```python ```python
@@ -387,7 +387,7 @@ that you saw that.
## Exercises ## Exercises
In Section 4, 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. Restart the interpreter and make a In this exercise, we will use that class. Restart the interpreter and make a
few instances: few instances:
@@ -444,7 +444,7 @@ the `__dict__` object:
Here, you really notice the fact that an instance is just a layer on Here, you really notice the fact that an instance is just a layer on
top of a dictionary. Note: it should be emphasized that direct 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.
### Exercise 5.3: The role of classes ### Exercise 5.3: The role of classes
@@ -457,7 +457,7 @@ to their associated class:
... look at output ... ... look at output ...
>>> ibm.__class__ >>> ibm.__class__
... look at output ... ... look at output ...
>>> >>>
``` ```
Try calling a method on the instances: Try calling a method on the instances:
@@ -520,7 +520,7 @@ However, notice that it is not part of the instance dictionary:
The reason you can access the `foo` attribute on instances is that The reason you can access the `foo` attribute on instances is that
Python always checks the class dictionary if it can't find something Python always checks the class dictionary if it can't find something
on the instance itself. on the instance itself.
Note: This part of the exercise illustrates something known as a class Note: This part of the exercise illustrates something known as a class
variable. Suppose, for instance, you have a class like this: variable. Suppose, for instance, you have a class like this:
@@ -567,7 +567,7 @@ two steps and something known as a bound method. For example:
>>> s(25) >>> s(25)
>>> goog.shares >>> goog.shares
75 75
>>> >>>
``` ```
Bound methods actually contain all of the pieces needed to call a Bound methods actually contain all of the pieces needed to call a
@@ -656,5 +656,5 @@ Here's how the `cost()` method of instance `n` above would be found:
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (4.4 Exceptions)](../04_Classes_objects/04_Defining_exceptions) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation) [Contents](../Contents.md) \| [Previous (4.4 Exceptions)](../04_Classes_objects/04_Defining_exceptions) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation)

View File

@@ -1,8 +1,8 @@
[Contents](../Contents) \| [Previous (5.1 Dictionaries Revisited)](01_Dicts_revisited) \| [Next (6 Generators)](../06_Generators/00_Overview) [Contents](../Contents.md) \| [Previous (5.1 Dictionaries Revisited)](01_Dicts_revisited) \| [Next (6 Generators)](../06_Generators/00_Overview)
# 5.2 Classes and Encapsulation # 5.2 Classes and Encapsulation
When writing classes, it is common to try and encapsulate internal details. When writing classes, it is common to try and encapsulate internal details.
This section introduces a few Python programming idioms for this including This section introduces a few Python programming idioms for this including
private variables and properties. private variables and properties.
@@ -279,7 +279,7 @@ are extracted:
Specifically, notice how you have to add the extra () to `cost` because it is a method. Specifically, notice how you have to add the extra () to `cost` because it is a method.
You can get rid of the extra () on `cost()` if you turn it into a property. You can get rid of the extra () on `cost()` if you turn it into a property.
Take your `Stock` class and modify it so that the cost calculation works like this: Take your `Stock` class and modify it so that the cost calculation works like this:
```python ```python
@@ -338,8 +338,8 @@ verify that new attributes can't be added:
>>> >>>
``` ```
When you use `__slots__`, Python uses a more efficient When you use `__slots__`, Python uses a more efficient
internal representation of objects. What happens if you try to internal representation of objects. What happens if you try to
inspect the underlying dictionary of `s` above? inspect the underlying dictionary of `s` above?
```python ```python
@@ -353,4 +353,4 @@ 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.
You should probably avoid `__slots__` on most other classes however. You should probably avoid `__slots__` on most other classes however.
[Contents](../Contents) \| [Previous (5.1 Dictionaries Revisited)](01_Dicts_revisited) \| [Next (6 Generators)](../06_Generators/00_Overview) [Contents](../Contents.md) \| [Previous (5.1 Dictionaries Revisited)](01_Dicts_revisited) \| [Next (6 Generators)](../06_Generators/00_Overview)

View File

@@ -2,15 +2,15 @@
Iteration (the `for`-loop) is one of the most common programming Iteration (the `for`-loop) is one of the most common programming
patterns in Python. Programs do a lot of iteration to process lists, patterns in Python. Programs do a lot of iteration to process lists,
read files, query databases, and more. One of the most powerful read files, query databases, and more. One of the most powerful
features of Python is the ability to customize and redefine iteration features of Python is the ability to customize and redefine iteration
in the form of a so-called "generator function." This section in the form of a so-called "generator function." This section
introduces this topic. By the end, you'll write some programs that introduces this topic. By the end, you'll write some programs that
process some real-time streaming data in an interesting way. process some real-time streaming data in an interesting way.
* [6.1 Iteration Protocol](01_Iteration_protocol) * [6.1 Iteration Protocol](01_Iteration_protocol.md)
* [6.2 Customizing Iteration with Generators](02_Customizing_iteration) * [6.2 Customizing Iteration with Generators](02_Customizing_iteration.md)
* [6.3 Producer/Consumer Problems and Workflows](03_Producers_consumers) * [6.3 Producer/Consumer Problems and Workflows](03_Producers_consumers.md)
* [6.4 Generator Expressions](04_More_generators) * [6.4 Generator Expressions](04_More_generators.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (5.2 Encapsulation)](../05_Object_model/02_Classes_encapsulation) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration) [Contents](../Contents.md) \| [Previous (5.2 Encapsulation)](../05_Object_model/02_Classes_encapsulation) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration)
# 6.1 Iteration Protocol # 6.1 Iteration Protocol
@@ -48,7 +48,7 @@ while True:
``` ```
All the objects that work with the `for-loop` implement this low-level All the objects that work with the `for-loop` implement this low-level
iteration protocol. iteration protocol.
Example: Manual iteration over a list. Example: Manual iteration over a list.
@@ -186,8 +186,8 @@ def read_portfolio(filename):
name, shares, and price. name, shares, and price.
''' '''
with open(filename) as file: with open(filename) as file:
portdicts = fileparse.parse_csv(file, portdicts = fileparse.parse_csv(file,
select=['name','shares','price'], select=['name','shares','price'],
types=[str,int,float]) types=[str,int,float])
portfolio = [ Stock(d['name'], d['shares'], d['price']) for d in portdicts ] portfolio = [ Stock(d['name'], d['shares'], d['price']) for d in portdicts ]
@@ -196,7 +196,7 @@ def read_portfolio(filename):
``` ```
Try running the `report.py` program. You will find that it fails spectacularly due to the fact Try running the `report.py` program. You will find that it fails spectacularly due to the fact
that `Portfolio` instances aren't iterable. that `Portfolio` instances aren't iterable.
```python ```python
>>> import report >>> import report
@@ -305,7 +305,7 @@ Stock('IBM', 50, 91.1)
True True
>>> 'AAPL' in portfolio >>> 'AAPL' in portfolio
False False
>>> >>>
``` ```
One important observation about this--generally code is considered One important observation about this--generally code is considered
@@ -314,4 +314,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.
[Contents](../Contents) \| [Previous (5.2 Encapsulation)](../05_Object_model/02_Classes_encapsulation) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration) [Contents](../Contents.md) \| [Previous (5.2 Encapsulation)](../05_Object_model/02_Classes_encapsulation) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (6.1 Iteration Protocol)](01_Iteration_protocol) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers) [Contents](../Contents.md) \| [Previous (6.1 Iteration Protocol)](01_Iteration_protocol) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers)
# 6.2 Customizing Iteration # 6.2 Customizing Iteration
@@ -137,7 +137,7 @@ name,shares,price
"IBM",50,91.10 "IBM",50,91.10
"IBM",100,70.44 "IBM",100,70.44
>>> >>>
``` ```
This is kind of interesting--the idea that you can hide a bunch of This is kind of interesting--the idea that you can hide a bunch of
@@ -209,14 +209,14 @@ lines of data whereas the statements at the end of the `while` loop are consumin
the data. A major feature of generator functions is that you can move all the data. A major feature of generator functions is that you can move all
of the data production code into a reusable function. of the data production code into a reusable function.
Modify the code in Exercise 6.5 so that the file-reading is performed by Modify the code in Exercise 6.5 so that the file-reading is performed by
a generator function `follow(filename)`. Make it so the following code a generator function `follow(filename)`. Make it so the following code
works: works:
```python ```python
>>> for line in follow('Data/stocklog.csv'): >>> for line in follow('Data/stocklog.csv'):
print(line, end='') print(line, end='')
... Should see lines of output produced here ... ... Should see lines of output produced here ...
``` ```
@@ -267,4 +267,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.
[Contents](../Contents) \| [Previous (6.1 Iteration Protocol)](01_Iteration_protocol) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers) [Contents](../Contents.md) \| [Previous (6.1 Iteration Protocol)](01_Iteration_protocol) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (6.2 Customizing Iteration)](02_Customizing_iteration) \| [Next (6.4 Generator Expressions)](04_More_generators) [Contents](../Contents.md) \| [Previous (6.2 Customizing Iteration)](02_Customizing_iteration) \| [Next (6.4 Generator Expressions)](04_More_generators)
# 6.3 Producers, Consumers and Pipelines # 6.3 Producers, Consumers and Pipelines
@@ -101,7 +101,7 @@ You will notice that data incrementally flows through the different functions.
## Exercises ## Exercises
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.
### Exercise 6.8: Setting up a simple pipeline ### Exercise 6.8: Setting up a simple pipeline
@@ -133,7 +133,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.
### Exercise 6.9: Setting up a more complex pipeline ### Exercise 6.9: Setting up a more complex pipeline
@@ -157,7 +157,7 @@ more actions.
Well, that's interesting. What you're seeing here is that the output of the 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.
### Exercise 6.10: Making more pipeline components ### Exercise 6.10: Making more pipeline components
@@ -274,12 +274,12 @@ and table format. For example::
```python ```python
>>> from ticker import ticker >>> from ticker import ticker
>>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'txt') >>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'txt')
Name Price Change Name Price Change
---------- ---------- ---------- ---------- ---------- ----------
GE 37.14 -0.18 GE 37.14 -0.18
MSFT 29.96 -0.09 MSFT 29.96 -0.09
CAT 78.03 -0.49 CAT 78.03 -0.49
AA 39.34 -0.32 AA 39.34 -0.32
... ...
>>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'csv') >>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'csv')
@@ -299,6 +299,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).
[Contents](../Contents) \| [Previous (6.2 Customizing Iteration)](02_Customizing_iteration) \| [Next (6.4 Generator Expressions)](04_More_generators) [Contents](../Contents.md) \| [Previous (6.2 Customizing Iteration)](02_Customizing_iteration) \| [Next (6.4 Generator Expressions)](04_More_generators)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview) [Contents](../Contents.md) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview)
# 6.4 More Generators # 6.4 More Generators
@@ -119,7 +119,7 @@ For example:
<generator object <genexpr> at 0x109207e60> <generator object <genexpr> at 0x109207e60>
>>> for n in squares: >>> for n in squares:
... print(n) ... print(n)
... ...
1 1
4 4
9 9
@@ -133,8 +133,8 @@ Thus, if you try another for-loop, you get nothing:
```python ```python
>>> for n in squares: >>> for n in squares:
... print(n) ... print(n)
... ...
>>> >>>
``` ```
### Exercise 6.14: Generator Expressions in Function Arguments ### Exercise 6.14: Generator Expressions in Function Arguments
@@ -180,4 +180,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) [Contents](../Contents.md) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview)

View File

@@ -10,10 +10,10 @@ It should be emphasized that the topics in this section are only meant
to serve as a very basic introduction to these ideas. You will need to serve as a very basic introduction to these ideas. You will need
to seek more advanced material to fill out details. to seek more advanced material to fill out details.
* [7.1 Variable argument functions](01_Variable_arguments) * [7.1 Variable argument functions](01_Variable_arguments.md)
* [7.2 Anonymous functions and lambda](02_Anonymous_function) * [7.2 Anonymous functions and lambda](02_Anonymous_function.md)
* [7.3 Returning function and closures](03_Returning_functions) * [7.3 Returning function and closures](03_Returning_functions.md)
* [7.4 Function decorators](04_Function_decorators) * [7.4 Function decorators](04_Function_decorators.md)
* [7.5 Static and class methods](05_Decorated_methods) * [7.5 Static and class methods](05_Decorated_methods.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,5 +1,5 @@
[Contents](../Contents) \| [Previous (6.4 Generator Expressions)](../06_Generators/04_More_generators) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function) [Contents](../Contents.md) \| [Previous (6.4 Generator Expressions)](../06_Generators/04_More_generators) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function)
# 7.1 Variable Arguments # 7.1 Variable Arguments
@@ -144,7 +144,7 @@ data. If you try to pass `data` directly, it doesn't work:
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 4 arguments (2 given) TypeError: __init__() takes exactly 4 arguments (2 given)
>>> >>>
``` ```
This is easily fixed using `*data` instead. Try this: This is easily fixed using `*data` instead. Try this:
@@ -177,11 +177,11 @@ def read_portfolio(filename):
name, shares, and price. name, shares, and price.
''' '''
with open(filename) as lines: with open(filename) as lines:
portdicts = fileparse.parse_csv(lines, portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'], select=['name','shares','price'],
types=[str,int,float]) types=[str,int,float])
portfolio = [ Stock(d['name'], d['shares'], d['price']) portfolio = [ Stock(d['name'], d['shares'], d['price'])
for d in portdicts ] for d in portdicts ]
return Portfolio(portfolio) return Portfolio(portfolio)
``` ```
@@ -201,8 +201,8 @@ def read_portfolio(filename, **opts):
name, shares, and price. name, shares, and price.
''' '''
with open(filename) as lines: with open(filename) as lines:
portdicts = fileparse.parse_csv(lines, portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'], select=['name','shares','price'],
types=[str,int,float], types=[str,int,float],
**opts) **opts)
@@ -230,4 +230,4 @@ Now, try silencing the errors:
>>> >>>
``` ```
[Contents](../Contents) \| [Previous (6.4 Generator Expressions)](../06_Generators/04_More_generators) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function) [Contents](../Contents.md) \| [Previous (6.4 Generator Expressions)](../06_Generators/04_More_generators) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions) [Contents](../Contents.md) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions)
# 7.2 Anonymous Functions and Lambda # 7.2 Anonymous Functions and Lambda
@@ -165,4 +165,4 @@ Note: `lambda` is a useful shortcut because it allows you to
define a special processing function directly in the call to `sort()` as define a special processing function directly in the call to `sort()` as
opposed to having to define a separate function first. opposed to having to define a separate function first.
[Contents](../Contents) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions) [Contents](../Contents.md) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions)

View File

@@ -1,8 +1,8 @@
[Contents](../Contents) \| [Previous (7.2 Anonymous Functions)](02_Anonymous_function) \| [Next (7.4 Decorators)](04_Function_decorators) [Contents](../Contents.md) \| [Previous (7.2 Anonymous Functions)](02_Anonymous_function) \| [Next (7.4 Decorators)](04_Function_decorators)
# 7.3 Returning Functions # 7.3 Returning Functions
This section introduces the idea of using functions to create other functions. This section introduces the idea of using functions to create other functions.
### Introduction ### Introduction
@@ -237,4 +237,4 @@ is often good.
Rewrite the `Stock` class in the file `stock.py` so that it uses typed properties Rewrite the `Stock` class in the file `stock.py` so that it uses typed properties
as shown. as shown.
[Contents](../Contents) \| [Previous (7.2 Anonymous Functions)](02_Anonymous_function) \| [Next (7.4 Decorators)](04_Function_decorators) [Contents](../Contents.md) \| [Previous (7.2 Anonymous Functions)](02_Anonymous_function) \| [Next (7.4 Decorators)](04_Function_decorators)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (7.3 Returning Functions)](03_Returning_functions) \| [Next (7.5 Decorated Methods)](05_Decorated_methods) [Contents](../Contents.md) \| [Previous (7.3 Returning Functions)](03_Returning_functions) \| [Next (7.5 Decorated Methods)](05_Decorated_methods)
# 7.4 Function Decorators # 7.4 Function Decorators
@@ -106,7 +106,7 @@ It is said to *decorate* the function.
There are many more subtle details to decorators than what has been presented here. There are many more subtle details to decorators than what has been presented here.
For example, using them in classes. Or using multiple decorators with a function. For example, using them in classes. Or using multiple decorators with a function.
However, the previous example is a good illustration of how their use tends to arise. However, the previous example is a good illustration of how their use tends to arise.
Usually, it's in response to repetitive code appearing across a wide range of Usually, it's in response to repetitive code appearing across a wide range of
function definitions. A decorator can move that code to a central definition. function definitions. A decorator can move that code to a central definition.
## Exercises ## Exercises
@@ -154,7 +154,7 @@ __main__.countdown : 0.076562
``` ```
Discussion: This `@timethis` decorator can be placed in front of any Discussion: This `@timethis` decorator can be placed in front of any
function definition. Thus, you might use it as a diagnostic tool for function definition. Thus, you might use it as a diagnostic tool for
performance tuning. performance tuning.
[Contents](../Contents) \| [Previous (7.3 Returning Functions)](03_Returning_functions) \| [Next (7.5 Decorated Methods)](05_Decorated_methods) [Contents](../Contents.md) \| [Previous (7.3 Returning Functions)](03_Returning_functions) \| [Next (7.5 Decorated Methods)](05_Decorated_methods)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (7.4 Decorators)](04_Function_decorators) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview) [Contents](../Contents.md) \| [Previous (7.4 Decorators)](04_Function_decorators) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview)
# 7.5 Decorated Methods # 7.5 Decorated Methods
@@ -123,8 +123,8 @@ def read_portfolio(filename, **opts):
name, shares, and price. name, shares, and price.
''' '''
with open(filename) as lines: with open(filename) as lines:
portdicts = fileparse.parse_csv(lines, portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'], select=['name','shares','price'],
types=[str,int,float], types=[str,int,float],
**opts) **opts)
@@ -163,7 +163,7 @@ class Portfolio:
... ...
``` ```
If you want to read a portfolio from a CSV file, maybe you should make a If you want to read a portfolio from a CSV file, maybe you should make a
class method for it: class method for it:
```python ```python
@@ -184,8 +184,8 @@ class Portfolio:
@classmethod @classmethod
def from_csv(cls, lines, **opts): def from_csv(cls, lines, **opts):
self = cls() self = cls()
portdicts = fileparse.parse_csv(lines, portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'], select=['name','shares','price'],
types=[str,int,float], types=[str,int,float],
**opts) **opts)
@@ -208,4 +208,4 @@ To use this new Portfolio class, you can now write code like this:
Make these changes to the `Portfolio` class and modify the `report.py` Make these changes to the `Portfolio` class and modify the `report.py`
code to use the class method. code to use the class method.
[Contents](../Contents) \| [Previous (7.4 Decorators)](04_Function_decorators) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview) [Contents](../Contents.md) \| [Previous (7.4 Decorators)](04_Function_decorators) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview)

View File

@@ -1,11 +1,11 @@
# 8. Overview # 8. Overview
This section introduces a few basic topics related to testing, This section introduces a few basic topics related to testing,
logging, and debugging. logging, and debugging.
* [8.1 Testing](01_Testing) * [8.1 Testing](01_Testing.md)
* [8.2 Logging, error handling and diagnostics](02_Logging) * [8.2 Logging, error handling and diagnostics](02_Logging.md)
* [8.3 Debugging](03_Debugging) * [8.3 Debugging](03_Debugging.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (7.5 Decorated Methods)](../07_Advanced_Topics/05_Decorated_methods) \| [Next (8.2 Logging)](02_Logging) [Contents](../Contents.md) \| [Previous (7.5 Decorated Methods)](../07_Advanced_Topics/05_Decorated_methods) \| [Next (8.2 Logging)](02_Logging)
# 8.1 Testing # 8.1 Testing
@@ -28,7 +28,7 @@ assert isinstance(10, int), 'Expected int'
It shouldn't be used to check the user-input (i.e., data entered It shouldn't be used to check the user-input (i.e., data entered
on a web form or something). It's purpose is more for internal on a web form or something). It's purpose is more for internal
checks and invariants (conditions that should always be true). checks and invariants (conditions that should always be true).
### Contract Programming ### Contract Programming
@@ -274,7 +274,7 @@ Once you're satisifed that it works, write additional unit tests that
check for the following: check for the following:
- Make sure the `s.cost` property returns the correct value (49010.0) - Make sure the `s.cost` property returns the correct value (49010.0)
- Make sure the `s.sell()` method works correctly. It should - Make sure the `s.sell()` method works correctly. It should
decrement the value of `s.shares` accordingly. decrement the value of `s.shares` accordingly.
- Make sure that the `s.shares` attribute can't be set to a non-integer value. - Make sure that the `s.shares` attribute can't be set to a non-integer value.
@@ -290,4 +290,4 @@ class TestStock(unittest.TestCase):
s.shares = '100' s.shares = '100'
``` ```
[Contents](../Contents) \| [Previous (7.5 Decorated Methods)](../07_Advanced_Topics/05_Decorated_methods) \| [Next (8.2 Logging)](02_Logging) [Contents](../Contents.md) \| [Previous (7.5 Decorated Methods)](../07_Advanced_Topics/05_Decorated_methods) \| [Next (8.2 Logging)](02_Logging)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (8.1 Testing)](01_Testing) \| [Next (8.3 Debugging)](03_Debugging) [Contents](../Contents.md) \| [Previous (8.1 Testing)](01_Testing) \| [Next (8.3 Debugging)](03_Debugging)
# 8.2 Logging # 8.2 Logging
@@ -131,7 +131,7 @@ uses logging doesn't have to worry about that.
### Exercise 8.2: Adding logging to a module ### Exercise 8.2: Adding logging to a module
In `fileparse.py`, there is some error handling related to In `fileparse.py`, there is some error handling related to
exceptions caused by bad input. It looks like this: exceptions caused by bad input. It looks like this:
```python ```python
@@ -262,7 +262,7 @@ steps to see that:
>>> a = report.read_portfolio('Data/missing.csv') >>> a = report.read_portfolio('Data/missing.csv')
WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23'] WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23']
WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44'] WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
>>> >>>
``` ```
You will notice that you don't see the output from the `log.debug()` You will notice that you don't see the output from the `log.debug()`
@@ -275,7 +275,7 @@ WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23']
DEBUG:fileparse:Row 4: Reason: invalid literal for int() with base 10: '' DEBUG:fileparse:Row 4: Reason: invalid literal for int() with base 10: ''
WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44'] WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
DEBUG:fileparse:Row 7: Reason: invalid literal for int() with base 10: '' DEBUG:fileparse:Row 7: Reason: invalid literal for int() with base 10: ''
>>> >>>
``` ```
Turn off all, but the most critical logging messages: Turn off all, but the most critical logging messages:
@@ -294,7 +294,7 @@ do this is to include some setup code that looks like this:
``` ```
# This file sets up basic configuration of the logging module. # This file sets up basic configuration of the logging module.
# Change settings here to adjust logging output as needed. # Change settings here to adjust logging output as needed.
import logging import logging
logging.basicConfig( logging.basicConfig(
filename = 'app.log', # Name of the log file (omit to use stderr) filename = 'app.log', # Name of the log file (omit to use stderr)
@@ -306,4 +306,4 @@ logging.basicConfig(
Again, you'd need to put this someplace in the startup steps of your Again, you'd need to put this someplace in the startup steps of your
program. For example, where would you put this in your `report.py` program? program. For example, where would you put this in your `report.py` program?
[Contents](../Contents) \| [Previous (8.1 Testing)](01_Testing) \| [Next (8.3 Debugging)](03_Debugging) [Contents](../Contents.md) \| [Previous (8.1 Testing)](01_Testing) \| [Next (8.3 Debugging)](03_Debugging)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (8.2 Logging)](02_Logging) \| [Next (9 Packages)](../09_Packages/00_Overview) [Contents](../Contents.md) \| [Previous (8.2 Logging)](02_Logging) \| [Next (9 Packages)](../09_Packages/00_Overview)
# 8.3 Debugging # 8.3 Debugging
@@ -158,4 +158,4 @@ For breakpoints location is one of the following.
It runs. Ship it! It runs. Ship it!
[Contents](../Contents) \| [Previous (8.2 Logging)](02_Logging) \| [Next (9 Packages)](../09_Packages/00_Overview) [Contents](../Contents.md) \| [Previous (8.2 Logging)](02_Logging) \| [Next (9 Packages)](../09_Packages/00_Overview)

View File

@@ -10,8 +10,8 @@ focus of this section is on some general code organization principles
that will prove useful no matter what tools you later use to give code that will prove useful no matter what tools you later use to give code
away or manage dependencies. away or manage dependencies.
* [9.1 Packages](01_Packages) * [9.1 Packages](01_Packages.md)
* [9.2 Third Party Modules](02_Third_party) * [9.2 Third Party Modules](02_Third_party.md)
* [9.3 Giving your code to others](03_Distribution) * [9.3 Giving your code to others](03_Distribution.md)
[Contents](../Contents) [Contents](../Contents.md)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (8.3 Debugging)](../08_Testing_debugging/03_Debugging) \| [Next (9.2 Third Party Packages)](02_Third_party) [Contents](../Contents.md) \| [Previous (8.3 Debugging)](../08_Testing_debugging/03_Debugging) \| [Next (9.2 Third Party Packages)](02_Third_party.md)
# 9.1 Packages # 9.1 Packages
@@ -119,7 +119,7 @@ import fileparse # BREAKS. fileparse not found
### Relative Imports ### Relative Imports
Instead of directly using the package name, Instead of directly using the package name,
you can use `.` to refer to the current package. you can use `.` to refer to the current package.
```python ```python
@@ -204,7 +204,7 @@ import sys
porty.pcost.main(sys.argv) porty.pcost.main(sys.argv)
``` ```
This script lives *outside* the package. For example, looking at the directory This script lives *outside* the package. For example, looking at the directory
structure: structure:
``` ```
@@ -375,7 +375,7 @@ Try running some of your prior scripts as a main program:
shell % cd porty-app shell % cd porty-app
shell % python3 -m porty.report portfolio.csv prices.csv txt shell % python3 -m porty.report portfolio.csv prices.csv txt
Name Shares Price Change Name Shares Price Change
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
AA 100 9.22 -22.98 AA 100 9.22 -22.98
IBM 50 106.28 15.18 IBM 50 106.28 15.18
CAT 150 35.46 -47.98 CAT 150 35.46 -47.98
@@ -408,7 +408,7 @@ can run it in that location:
shell % cd porty-app shell % cd porty-app
shell % python3 print-report.py portfolio.csv prices.csv txt shell % python3 print-report.py portfolio.csv prices.csv txt
Name Shares Price Change Name Shares Price Change
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
AA 100 9.22 -22.98 AA 100 9.22 -22.98
IBM 50 106.28 15.18 IBM 50 106.28 15.18
CAT 150 35.46 -47.98 CAT 150 35.46 -47.98
@@ -441,4 +441,4 @@ porty-app/
typedproperty.py typedproperty.py
``` ```
[Contents](../Contents) \| [Previous (8.3 Debugging)](../08_Testing_debugging/03_Debugging) \| [Next (9.2 Third Party Packages)](02_Third_party) [Contents](../Contents.md) \| [Previous (8.3 Debugging)](../08_Testing_debugging/03_Debugging) \| [Next (9.2 Third Party Packages)](02_Third_party.md)

View File

@@ -1,13 +1,13 @@
[Contents](../Contents) \| [Previous (9.1 Packages)](01_Packages) \| [Next (9.3 Distribution)](03_Distribution) [Contents](../Contents.md) \| [Previous (9.1 Packages)](01_Packages) \| [Next (9.3 Distribution)](03_Distribution)
# 9.2 Third Party Modules # 9.2 Third Party Modules
Python has a large library of built-in modules (*batteries included*). Python has a large library of built-in modules (*batteries included*).
There are even more third party modules. Check them in the [Python Package Index](https://pypi.org/) or PyPi. There are even more third party modules. Check them in the [Python Package Index](https://pypi.org/) or PyPi.
Or just do a Google search for a specific topic. Or just do a Google search for a specific topic.
How to handle third-party dependencies is an ever-evolving topic with How to handle third-party dependencies is an ever-evolving topic with
Python. This section merely covers the basics to help you wrap Python. This section merely covers the basics to help you wrap
your brain around how it works. your brain around how it works.
@@ -24,7 +24,7 @@ checked by the `import` statement. Look at it:
``` ```
If you import something and it's not located in one of those If you import something and it's not located in one of those
directories, you will get an `ImportError` exception. directories, you will get an `ImportError` exception.
### Standard Library Modules ### Standard Library Modules
@@ -39,19 +39,19 @@ by trying a short test:
>>> >>>
``` ```
Simply looking at a module in the REPL is a good debugging tip Simply looking at a module in the REPL is a good debugging tip
to know about. It will show you the location of the file. to know about. It will show you the location of the file.
### Third-party Modules ### Third-party Modules
Third party modules are usually located in a dedicated Third party modules are usually located in a dedicated
`site-packages` directory. You'll see it if you perform `site-packages` directory. You'll see it if you perform
the same steps as above: the same steps as above:
```python ```python
>>> import numpy >>> import numpy
<module 'numpy' from '/usr/local/lib/python3.6/site-packages/numpy/__init__.py'> <module 'numpy' from '/usr/local/lib/python3.6/site-packages/numpy/__init__.py'>
>>> >>>
``` ```
Again, looking at a module is a good debugging tip if you're Again, looking at a module is a good debugging tip if you're
@@ -114,7 +114,7 @@ For example:
For the purposes of experimenting and trying out different For the purposes of experimenting and trying out different
packages, a virtual environment will usually work fine. If, packages, a virtual environment will usually work fine. If,
on the other hand, you're creating an application and it on the other hand, you're creating an application and it
has specific package dependencies, that is a slightly has specific package dependencies, that is a slightly
different problem. different problem.
### Handling Third-Party Dependencies in Your Application ### Handling Third-Party Dependencies in Your Application
@@ -135,7 +135,7 @@ I refer you to the [Python Packaging User Guide](https://packaging.python.org).
See if you can recreate the steps of making a virtual environment and installing See if you can recreate the steps of making a virtual environment and installing
pandas into it as shown above. pandas into it as shown above.
[Contents](../Contents) \| [Previous (9.1 Packages)](01_Packages) \| [Next (9.3 Distribution)](03_Distribution) [Contents](../Contents.md) \| [Previous (9.1 Packages)](01_Packages) \| [Next (9.3 Distribution)](03_Distribution)

View File

@@ -1,4 +1,4 @@
[Contents](../Contents) \| [Previous (9.2 Third Party Packages)](02_Third_party) \| [Next (The End)](TheEnd) [Contents](../Contents.md) \| [Previous (9.2 Third Party Packages)](02_Third_party.md) \| [Next (The End)](TheEnd.md)
# 9.3 Distribution # 9.3 Distribution
@@ -8,7 +8,7 @@ information, you'll need to consult the [Python Packaging User Guide](https://pa
### Creating a setup.py file ### Creating a setup.py file
Add a `setup.py` file to the top-level of your project directory. Add a `setup.py` file to the top-level of your project directory.
```python ```python
# setup.py # setup.py
@@ -20,7 +20,7 @@ setuptools.setup(
author="Your Name", author="Your Name",
author_email="you@example.com", author_email="you@example.com",
description="Practical Python Code", description="Practical Python Code",
packages=setuptools.find_packages(), packages=setuptools.find_packages(),
) )
``` ```
@@ -45,7 +45,7 @@ bash % python setup.py sdist
``` ```
This will create a `.tar.gz` or `.zip` file in the directory `dist/`. That file is something This will create a `.tar.gz` or `.zip` file in the directory `dist/`. That file is something
that you can now give away to others. that you can now give away to others.
### Installing your code ### Installing your code
@@ -72,13 +72,13 @@ this course. We've only taken a tiny first step.
Take the `porty-app/` code you created for Exercise 9.3 and see if you Take the `porty-app/` code you created for Exercise 9.3 and see if you
can recreate the steps described here. Specifically, add a `setup.py` can recreate the steps described here. Specifically, add a `setup.py`
file and a `MANIFEST.in` file to the top-level directory. file and a `MANIFEST.in` file to the top-level directory.
Create a source distribution file by running `python setup.py sdist`. Create a source distribution file by running `python setup.py sdist`.
As a final step, see if you can install your package into a Python As a final step, see if you can install your package into a Python
virtual environment. virtual environment.
[Contents](../Contents) \| [Previous (9.2 Third Party Packages)](02_Third_party) \| [Next (The End)](TheEnd) [Contents](../Contents.md) \| [Previous (9.2 Third Party Packages)](02_Third_party.md) \| [Next (The End)](TheEnd.md)

View File

@@ -6,5 +6,5 @@ May your future Python hacking be fun and productive!
I'm always happy to get feedback. You can find me at [https://dabeaz.com](https://dabeaz.com) I'm always happy to get feedback. You can find me at [https://dabeaz.com](https://dabeaz.com)
or on Twitter at [@dabeaz](https://twitter.com/dabeaz). - David Beazley. or on Twitter at [@dabeaz](https://twitter.com/dabeaz). - David Beazley.
[Contents](../Contents) \| [Home](../..) [Contents](../Contents.md) \| [Home](../..)

View File

@@ -2,16 +2,16 @@
## Table of Contents ## Table of Contents
* [0. Course Setup (READ FIRST!)](00_Setup) * [0. Course Setup (READ FIRST!)](00_Setup.md)
* [1. Introduction to Python](01_Introduction/00_Overview) * [1. Introduction to Python](01_Introduction/00_Overview.md)
* [2. Working with Data](02_Working_with_data/00_Overview) * [2. Working with Data](02_Working_with_data/00_Overview.md)
* [3. Program Organization](03_Program_organization/00_Overview) * [3. Program Organization](03_Program_organization/00_Overview.md)
* [4. Classes and Objects](04_Classes_objects/00_Overview) * [4. Classes and Objects](04_Classes_objects/00_Overview.md)
* [5. The Inner Workings of Python Objects](05_Object_model/00_Overview) * [5. The Inner Workings of Python Objects](05_Object_model/00_Overview.md)
* [6. Generators](06_Generators/00_Overview) * [6. Generators](06_Generators/00_Overview.md)
* [7. A Few Advanced Topics](07_Advanced_Topics/00_Overview) * [7. A Few Advanced Topics](07_Advanced_Topics/00_Overview.md)
* [8. Testing, Logging, and Debugging](08_Testing_debugging/00_Overview) * [8. Testing, Logging, and Debugging](08_Testing_debugging/00_Overview.md)
* [9. Packages](09_Packages/00_Overview) * [9. Packages](09_Packages/00_Overview.md)
[Home](..) [Home](..)