Merge pull request #3 from advishnuprasad/fix-broken-links
Fix broken links
This commit is contained in:
@@ -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
|
||||
solutions first.
|
||||
|
||||
[Contents](Contents)
|
||||
[Contents](Contents.md)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
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,
|
||||
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.2 A First Program](02_Hello_world)
|
||||
* [1.3 Numbers](03_Numbers)
|
||||
* [1.4 Strings](04_Strings)
|
||||
* [1.5 Lists](05_Lists)
|
||||
* [1.6 Files](06_Files)
|
||||
* [1.7 Functions](07_Functions)
|
||||
* [1.1 Introducing Python](01_Python.md)
|
||||
* [1.2 A First Program](02_Hello_world.md)
|
||||
* [1.3 Numbers](03_Numbers.md)
|
||||
* [1.4 Strings](04_Strings.md)
|
||||
* [1.5 Lists](05_Lists.md)
|
||||
* [1.6 Files](06_Files.md)
|
||||
* [1.7 Functions](07_Functions.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
### What is Python?
|
||||
|
||||
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
|
||||
of Python is loosely inspired by elements of C programming.
|
||||
|
||||
@@ -40,12 +40,12 @@ able to type `python` like this:
|
||||
|
||||
```
|
||||
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
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> print("hello world")
|
||||
hello world
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -51,7 +51,7 @@ hello world
|
||||
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
|
||||
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
|
||||
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,
|
||||
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
|
||||
>>> 37 * 42
|
||||
@@ -109,7 +109,7 @@ C:\SomeFolder>c:\python36\python hello.py
|
||||
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
|
||||
such as `hello.py`.
|
||||
|
||||
@@ -265,7 +265,7 @@ Indentation groups the following statements together as the operations that repe
|
||||
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
|
||||
readability. It does not affect the execution.
|
||||
|
||||
@@ -275,7 +275,7 @@ readability. It does not affect the execution.
|
||||
* Use 4 spaces per level.
|
||||
* 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:
|
||||
|
||||
```python
|
||||
@@ -464,7 +464,7 @@ NameError: name 'days' is not defined
|
||||
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
|
||||
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?
|
||||
* What is the error?
|
||||
@@ -472,4 +472,4 @@ an identifying filename and line number.
|
||||
* 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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -55,7 +55,7 @@ x / y Divide (produces a float)
|
||||
x // y Floor Divide (produces an integer)
|
||||
x % y Modulo (remainder)
|
||||
x ** y Power
|
||||
x << n Bit shift left
|
||||
x << n Bit shift left
|
||||
x >> n Bit shift right
|
||||
x & y Bit-wise AND
|
||||
x | y Bit-wise OR
|
||||
@@ -170,7 +170,7 @@ Try it out.
|
||||
## Exercises
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
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:
|
||||
|
||||
```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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -299,7 +299,7 @@ Verify this by trying to change the first character of `symbols` to a lower-case
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: 'str' object does not support item assignment
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
### Exercise 1.14: String concatenation
|
||||
@@ -408,10 +408,10 @@ To do that, use an f-string. For example:
|
||||
>>> price = 91.1
|
||||
>>> f'{shares} shares of {name} at ${price:0.2f}'
|
||||
'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.
|
||||
|
||||
|
||||
@@ -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
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -98,7 +98,7 @@ for name in names:
|
||||
|
||||
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
|
||||
names = ['Elwood','Jake','Curtis']
|
||||
@@ -267,7 +267,7 @@ Use the `append()` method to add the symbol `'RHT'` to end of `symlist`.
|
||||
>>> # append 'RHT'
|
||||
>>> symlist
|
||||
['HPQ', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT']
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
@@ -63,7 +63,7 @@ Read a file line-by-line by iterating.
|
||||
```python
|
||||
with open(filename, 'rt') as file:
|
||||
for line in file:
|
||||
# Process the line
|
||||
# Process the line
|
||||
```
|
||||
|
||||
### 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.
|
||||
Thus, you normally wouldn’t call it directly unless you’re 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
|
||||
reading CSV files. This is true--and it works pretty well.
|
||||
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
|
||||
familiar format to most coders and it's relatively easy to work with
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,7 +41,7 @@ import math
|
||||
x = math.sqrt(10)
|
||||
|
||||
import urllib.request
|
||||
u = urllib.request.urlopen('http://www.python.org/')
|
||||
u = urllib.request.urlopen('http://www.python.org/')
|
||||
data = u.read()
|
||||
```
|
||||
|
||||
@@ -49,7 +49,7 @@ We will cover libraries and modules in more detail later.
|
||||
|
||||
### 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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
function takes a filename as input, reads the portfolio data in that
|
||||
file, and returns the total cost of the portfolio as a float.
|
||||
@@ -278,4 +278,4 @@ Total cost: 44671.15
|
||||
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)
|
||||
@@ -6,12 +6,12 @@ lists, sets, and dictionaries and discusses common data handling
|
||||
idioms. The last part of this section dives a little deeper
|
||||
into Python's underlying object model.
|
||||
|
||||
* [2.1 Datatypes and Data Structures](01_Datatypes)
|
||||
* [2.2 Containers](02_Containers)
|
||||
* [2.3 Formatted Output](03_Formatting)
|
||||
* [2.4 Sequences](04_Sequences)
|
||||
* [2.5 Collections module](05_Collections)
|
||||
* [2.6 List comprehensions](06_List_comprehension)
|
||||
* [2.7 Object model](07_Objects)
|
||||
* [2.1 Datatypes and Data Structures](01_Datatypes.md)
|
||||
* [2.2 Containers](02_Containers.md)
|
||||
* [2.3 Formatted Output](03_Formatting.md)
|
||||
* [2.4 Sequences](04_Sequences.md)
|
||||
* [2.5 Collections module](05_Collections.md)
|
||||
* [2.6 List comprehensions](06_List_comprehension.md)
|
||||
* [2.7 Object model](07_Objects.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
@@ -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.md)
|
||||
|
||||
# 2.1 Datatypes and Data structures
|
||||
|
||||
@@ -242,7 +242,7 @@ shares and the price:
|
||||
```
|
||||
|
||||
Is math broken in Python? What’s the deal with the answer of
|
||||
3220.0000000000005?
|
||||
3220.0000000000005?
|
||||
|
||||
This is an artifact of the floating point hardware on your computer
|
||||
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.md)
|
||||
|
||||
@@ -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.md) \| [Next (2.3 Formatting)](03_Formatting.md)
|
||||
|
||||
# 2.2 Containers
|
||||
|
||||
This section discusses lists, dictionaries, and sets.
|
||||
This section discusses lists, dictionaries, and sets.
|
||||
|
||||
### 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
|
||||
|
||||
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
|
||||
performed a simple calculation.
|
||||
|
||||
@@ -442,5 +442,4 @@ 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
|
||||
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.md) \| [Next (2.3 Formatting)](03_Formatting.md)
|
||||
|
||||
@@ -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.md) \| [Next (2.4 Sequences)](04_Sequences.md)
|
||||
|
||||
# 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
|
||||
supplied dictionary.
|
||||
supplied dictionary.
|
||||
|
||||
### 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
|
||||
|
||||
@@ -299,4 +299,4 @@ How would you modify your code so that the price includes the currency symbol ($
|
||||
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.md) \| [Next (2.4 Sequences)](04_Sequences.md)
|
||||
|
||||
@@ -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.md) \| [Next (2.5 Collections)](05_Collections.md)
|
||||
|
||||
# 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.md) \| [Next (2.5 Collections)](05_Collections.md)
|
||||
|
||||
@@ -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.md) \| [Next (2.6 List Comprehensions)](06_List_comprehension.md)
|
||||
|
||||
# 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,
|
||||
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.md) \| [Next (2.6 List Comprehensions)](06_List_comprehension.md)
|
||||
@@ -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.md) \| [Next (2.7 Object Model)](07_Objects.md)
|
||||
|
||||
# 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.
|
||||
|
||||
### Commentary
|
||||
### Commentary
|
||||
|
||||
List comprehensions are commonly used in Python as an efficient means
|
||||
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
|
||||
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.md) \| [Next (2.7 Object Model)](07_Objects.md)
|
||||
|
||||
@@ -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.md) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview.md)
|
||||
|
||||
# 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.
|
||||
|
||||
### Assignment
|
||||
@@ -451,4 +451,4 @@ Bonus: How would you modify this example to additionally parse the
|
||||
Spend some time to ponder what you’ve done in this exercise. We’ll
|
||||
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.md) \| [Next (3 Program Organization)](../03_Program_organization/00_Overview.md)
|
||||
|
||||
@@ -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
|
||||
some useful code templates for writing more useful scripts.
|
||||
|
||||
* [3.1 Functions and Script Writing](01_Script)
|
||||
* [3.2 More Detail on Functions](02_More_functions)
|
||||
* [3.3 Exception Handling](03_Error_checking)
|
||||
* [3.4 Modules](04_Modules)
|
||||
* [3.5 Main module](05_Main_module)
|
||||
* [3.6 Design Discussion about Embracing Flexibilty](06_Design_discussion)
|
||||
* [3.1 Functions and Script Writing](01_Script.md)
|
||||
* [3.2 More Detail on Functions](02_More_functions.md)
|
||||
* [3.3 Exception Handling](03_Error_checking.md)
|
||||
* [3.4 Modules](04_Modules.md)
|
||||
* [3.5 Main module](05_Main_module.md)
|
||||
* [3.6 Design Discussion about Embracing Flexibilty](06_Design_discussion.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
@@ -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.md) \| [Next (3.2 More on Functions)](02_More_functions.md)
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
@@ -153,7 +153,7 @@ and mysterious side-effects. Your main goals: *Modularity* and *Predictability*
|
||||
|
||||
### 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
|
||||
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.
|
||||
However, they may be used by IDEs, code checkers, and other tools
|
||||
to do more.
|
||||
to do more.
|
||||
|
||||
## 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
|
||||
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.md) \| [Next (3.2 More on Functions)](02_More_functions.md)
|
||||
@@ -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.md) \| [Next (3.3 Error Checking)](03_Error_checking.md)
|
||||
|
||||
# 3.2 More on Functions
|
||||
|
||||
@@ -273,7 +273,7 @@ Start this exercise by creating a new file called
|
||||
### Exercise 3.3: Reading CSV Files
|
||||
|
||||
To start, let’s 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:
|
||||
|
||||
```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, here’s one way to do it:
|
||||
|
||||
```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:
|
||||
|
||||
```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
|
||||
`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.md) \| [Next (3.3 Error Checking)](03_Error_checking.md)
|
||||
|
||||
@@ -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.md) \| [Next (3.4 Modules)](04_Modules.md)
|
||||
|
||||
# 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
|
||||
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
|
||||
reasonable. Only catch the errors you can actually handle. Let
|
||||
@@ -402,4 +402,4 @@ most programs. As a general rule, you shouldn’t silently ignore
|
||||
errors. Instead, it’s better to report problems and to give the user
|
||||
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.md) \| [Next (3.4 Modules)](04_Modules.md)
|
||||
|
||||
@@ -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.md) \| [Next (3.5 Main Module)](05_Main_module.md)
|
||||
|
||||
# 3.4 Modules
|
||||
|
||||
This section introduces the concept of modules and working with functions that span
|
||||
multiple files.
|
||||
This section introduces the concept of modules and working with functions that span
|
||||
multiple files.
|
||||
|
||||
### 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`,
|
||||
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
|
||||
the interpreter.
|
||||
the interpreter.
|
||||
|
||||
### Locating Modules
|
||||
|
||||
@@ -214,7 +214,7 @@ not readily accessible from the current working directory.
|
||||
For this exercise involving modules, it is critically important to
|
||||
make sure you are running Python in a proper environment. Modules are
|
||||
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.
|
||||
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
|
||||
@@ -338,4 +338,4 @@ also contains `read_portfolio()` and `read_prices()` functions. And
|
||||
finally, `pcost.py` which computes the portfolio cost, but makes use
|
||||
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.md) \| [Next (3.5 Main Module)](05_Main_module.md)
|
||||
|
||||
@@ -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.md) \| [Next (3.6 Design Discussion)](06_Design_discussion.md)
|
||||
|
||||
# 3.5 Main Module
|
||||
|
||||
@@ -303,4 +303,4 @@ bash $ python3 pcost.py Data/portfolio.csv
|
||||
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.md) \| [Next (3.6 Design Discussion)](06_Design_discussion.md)
|
||||
@@ -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.md) \| [Next (4 Classes)](../04_Classes_objects/00_Overview.md)
|
||||
|
||||
# 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
|
||||
|
||||
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:
|
||||
|
||||
```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
|
||||
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
|
||||
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.md) \| [Next (4 Classes)](../04_Classes_objects/00_Overview.md)
|
||||
@@ -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,
|
||||
and defining new exceptions.
|
||||
|
||||
* [4.1 Introducing Classes](01_Class)
|
||||
* [4.2 Inheritance](02_Inheritance)
|
||||
* [4.3 Special Methods](03_Special_methods)
|
||||
* [4.4 Defining new Exception](04_Defining_exceptions)
|
||||
* [4.1 Introducing Classes](01_Class.md)
|
||||
* [4.2 Inheritance](02_Inheritance.md)
|
||||
* [4.3 Special Methods](03_Special_methods.md)
|
||||
* [4.4 Defining new Exception](04_Defining_exceptions.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
@@ -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.md) \| [Next (4.2 Inheritance)](02_Inheritance.md)
|
||||
|
||||
# 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 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 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 0x10ca6f7b8>]
|
||||
>>> sum([s.cost() for s in portfolio])
|
||||
44671.15
|
||||
@@ -283,16 +283,16 @@ You should be able to run your functions the same as before:
|
||||
44671.15
|
||||
>>> import report
|
||||
>>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv')
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
MSFT 200 20.89 -30.34
|
||||
GE 95 13.48 -26.89
|
||||
MSFT 50 20.89 -44.21
|
||||
IBM 100 106.28 35.84
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
MSFT 200 20.89 -30.34
|
||||
GE 95 13.48 -26.89
|
||||
MSFT 50 20.89 -44.21
|
||||
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.md) \| [Next (4.2 Inheritance)](02_Inheritance.md)
|
||||
|
||||
@@ -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.md) \| [Next (4.3 Special methods)](03_Special_methods.md)
|
||||
|
||||
# 4.2 Inheritance
|
||||
|
||||
@@ -158,7 +158,7 @@ class Rectangle(Shape):
|
||||
```
|
||||
|
||||
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
|
||||
to customize it.
|
||||
|
||||
@@ -170,7 +170,7 @@ class CustomHandler(TCPHandler):
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
@@ -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.*
|
||||
|
||||
### `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
|
||||
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:
|
||||
|
||||
```python
|
||||
@@ -298,7 +298,7 @@ class TableFormatter:
|
||||
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
|
||||
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.
|
||||
'''
|
||||
# Read data files
|
||||
# Read data files
|
||||
portfolio = read_portfolio(portfoliofile)
|
||||
prices = read_prices(pricefile)
|
||||
|
||||
@@ -355,7 +355,7 @@ Run this new code:
|
||||
... 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.
|
||||
|
||||
### 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.
|
||||
'''
|
||||
# Read data files
|
||||
# Read data files
|
||||
portfolio = read_portfolio(portfoliofile)
|
||||
prices = read_prices(pricefile)
|
||||
|
||||
@@ -446,7 +446,7 @@ def portfolio_report(portfoliofile, pricefile):
|
||||
'''
|
||||
Make a stock report given portfolio and price data files.
|
||||
'''
|
||||
# Read data files
|
||||
# Read data files
|
||||
portfolio = read_portfolio(portfoliofile)
|
||||
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
|
||||
|
||||
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
|
||||
change any of the existing code. For example, if you wrote a program
|
||||
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.
|
||||
'''
|
||||
# Read data files
|
||||
# Read data files
|
||||
portfolio = read_portfolio(portfoliofile)
|
||||
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.
|
||||
'''
|
||||
# Read data files
|
||||
# Read data files
|
||||
portfolio = read_portfolio(portfoliofile)
|
||||
prices = read_prices(pricefile)
|
||||
|
||||
@@ -568,15 +568,15 @@ an optional argument specifying the output format. For example:
|
||||
|
||||
```python
|
||||
>>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv', 'txt')
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
MSFT 200 20.89 -30.34
|
||||
GE 95 13.48 -26.89
|
||||
MSFT 50 20.89 -44.21
|
||||
IBM 100 106.28 35.84
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
MSFT 200 20.89 -30.34
|
||||
GE 95 13.48 -26.89
|
||||
MSFT 50 20.89 -44.21
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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.md) \| [Next (4.3 Special methods)](03_Special_methods.md)
|
||||
|
||||
@@ -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.md) \| [Next (4.4 Exceptions)](04_Defining_exceptions.md)
|
||||
|
||||
# 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
|
||||
trailing parentheses. For example, `s.cost()` or `f.close()`.
|
||||
trailing parentheses. For example, `s.cost()` or `f.close()`.
|
||||
|
||||
### Attribute Access
|
||||
|
||||
@@ -276,7 +276,7 @@ it should work:
|
||||
|
||||
>>> print_table(portfolio, ['name','shares','price'], formatter)
|
||||
name shares price
|
||||
---------- ---------- ----------
|
||||
---------- ---------- ----------
|
||||
AA 100 32.2
|
||||
IBM 50 91.1
|
||||
CAT 150 83.44
|
||||
@@ -284,8 +284,8 @@ it should work:
|
||||
GE 95 40.37
|
||||
MSFT 50 65.1
|
||||
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.md) \| [Next (4.4 Exceptions)](04_Defining_exceptions.md)
|
||||
|
||||
|
||||
@@ -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.md) \| [Next (5 Object Model)](../05_Object_model/00_Overview.md)
|
||||
|
||||
# 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.md) \| [Next (5 Object Model)](../05_Object_model/00_Overview.md)
|
||||
|
||||
@@ -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
|
||||
work. So, that's why we're covering it.
|
||||
|
||||
* [5.1 Dictionaries Revisited (Object Implementation)](01_Dicts_revisited)
|
||||
* [5.2 Encapsulation Techniques](02_Classes_encapsulation)
|
||||
* [5.1 Dictionaries Revisited (Object Implementation)](01_Dicts_revisited.md)
|
||||
* [5.2 Encapsulation Techniques](02_Classes_encapsulation.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
|
||||
@@ -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.md) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation.md)
|
||||
|
||||
# 5.1 Dictionaries Revisited
|
||||
|
||||
@@ -279,7 +279,7 @@ about class ordering.
|
||||
* Children are always checked before parents
|
||||
* 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.
|
||||
|
||||
```python
|
||||
@@ -387,7 +387,7 @@ that you saw that.
|
||||
|
||||
## 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
|
||||
few instances:
|
||||
|
||||
@@ -444,7 +444,7 @@ the `__dict__` object:
|
||||
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
|
||||
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
|
||||
|
||||
@@ -457,7 +457,7 @@ to their associated class:
|
||||
... look at output ...
|
||||
>>> ibm.__class__
|
||||
... look at output ...
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
>>> goog.shares
|
||||
75
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
Bound methods actually contain all of the pieces needed to call a
|
||||
@@ -656,5 +656,4 @@ 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.md) \| [Next (5.2 Encapsulation)](02_Classes_encapsulation.md)
|
||||
|
||||
@@ -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.md) \| [Next (6 Generators)](../06_Generators/00_Overview.md)
|
||||
|
||||
# 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
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
```python
|
||||
@@ -338,8 +338,8 @@ verify that new attributes can't be added:
|
||||
>>>
|
||||
```
|
||||
|
||||
When you use `__slots__`, Python uses a more efficient
|
||||
internal representation of objects. What happens if you try to
|
||||
When you use `__slots__`, Python uses a more efficient
|
||||
internal representation of objects. What happens if you try to
|
||||
inspect the underlying dictionary of `s` above?
|
||||
|
||||
```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.
|
||||
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.md) \| [Next (6 Generators)](../06_Generators/00_Overview.md)
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
Iteration (the `for`-loop) is one of the most common programming
|
||||
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
|
||||
in the form of a so-called "generator function." This section
|
||||
introduces this topic. By the end, you'll write some programs that
|
||||
process some real-time streaming data in an interesting way.
|
||||
|
||||
* [6.1 Iteration Protocol](01_Iteration_protocol)
|
||||
* [6.2 Customizing Iteration with Generators](02_Customizing_iteration)
|
||||
* [6.3 Producer/Consumer Problems and Workflows](03_Producers_consumers)
|
||||
* [6.4 Generator Expressions](04_More_generators)
|
||||
* [6.1 Iteration Protocol](01_Iteration_protocol.md)
|
||||
* [6.2 Customizing Iteration with Generators](02_Customizing_iteration.md)
|
||||
* [6.3 Producer/Consumer Problems and Workflows](03_Producers_consumers.md)
|
||||
* [6.4 Generator Expressions](04_More_generators.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
@@ -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.md) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration.md)
|
||||
|
||||
# 6.1 Iteration Protocol
|
||||
|
||||
@@ -48,7 +48,7 @@ while True:
|
||||
```
|
||||
|
||||
All the objects that work with the `for-loop` implement this low-level
|
||||
iteration protocol.
|
||||
iteration protocol.
|
||||
|
||||
Example: Manual iteration over a list.
|
||||
|
||||
@@ -186,8 +186,8 @@ def read_portfolio(filename):
|
||||
name, shares, and price.
|
||||
'''
|
||||
with open(filename) as file:
|
||||
portdicts = fileparse.parse_csv(file,
|
||||
select=['name','shares','price'],
|
||||
portdicts = fileparse.parse_csv(file,
|
||||
select=['name','shares','price'],
|
||||
types=[str,int,float])
|
||||
|
||||
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
|
||||
that `Portfolio` instances aren't iterable.
|
||||
that `Portfolio` instances aren't iterable.
|
||||
|
||||
```python
|
||||
>>> import report
|
||||
@@ -305,7 +305,7 @@ Stock('IBM', 50, 91.1)
|
||||
True
|
||||
>>> 'AAPL' in portfolio
|
||||
False
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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
|
||||
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.md) \| [Next (6.2 Customizing Iteration)](02_Customizing_iteration.md)
|
||||
@@ -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.md) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers.md)
|
||||
|
||||
# 6.2 Customizing Iteration
|
||||
|
||||
@@ -137,7 +137,7 @@ name,shares,price
|
||||
|
||||
"IBM",50,91.10
|
||||
"IBM",100,70.44
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
works:
|
||||
|
||||
```python
|
||||
>>> for line in follow('Data/stocklog.csv'):
|
||||
print(line, end='')
|
||||
|
||||
|
||||
... 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.
|
||||
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.md) \| [Next (6.3 Producer/Consumer)](03_Producers_consumers.md)
|
||||
@@ -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.md) \| [Next (6.4 Generator Expressions)](04_More_generators.md)
|
||||
|
||||
# 6.3 Producers, Consumers and Pipelines
|
||||
|
||||
@@ -101,7 +101,7 @@ You will notice that data incrementally flows through the different functions.
|
||||
|
||||
## 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.
|
||||
You’re going to use the `follow()` function you wrote in the previous exercise.
|
||||
|
||||
### 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
|
||||
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
|
||||
|
||||
@@ -157,7 +157,7 @@ more actions.
|
||||
|
||||
Well, that's interesting. What you're seeing here is that the output of the
|
||||
`follow()` function has been piped into the `csv.reader()` function and we're
|
||||
now getting a sequence of split rows.
|
||||
now getting a sequence of split rows.
|
||||
|
||||
### Exercise 6.10: Making more pipeline components
|
||||
|
||||
@@ -274,12 +274,12 @@ and table format. For example::
|
||||
```python
|
||||
>>> from ticker import ticker
|
||||
>>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'txt')
|
||||
Name Price Change
|
||||
---------- ---------- ----------
|
||||
GE 37.14 -0.18
|
||||
MSFT 29.96 -0.09
|
||||
CAT 78.03 -0.49
|
||||
AA 39.34 -0.32
|
||||
Name Price Change
|
||||
---------- ---------- ----------
|
||||
GE 37.14 -0.18
|
||||
MSFT 29.96 -0.09
|
||||
CAT 78.03 -0.49
|
||||
AA 39.34 -0.32
|
||||
...
|
||||
|
||||
>>> ticker('Data/portfolio.csv', 'Data/stocklog.csv', 'csv')
|
||||
@@ -299,6 +299,4 @@ pipelines. In addition, you can create functions that package a
|
||||
series of pipeline stages into a single function call (for example,
|
||||
the `parse_stock_data()` function).
|
||||
|
||||
[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.md) \| [Next (6.4 Generator Expressions)](04_More_generators.md)
|
||||
|
||||
@@ -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.md) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview.md)
|
||||
|
||||
# 6.4 More Generators
|
||||
|
||||
@@ -119,7 +119,7 @@ For example:
|
||||
<generator object <genexpr> at 0x109207e60>
|
||||
>>> for n in squares:
|
||||
... print(n)
|
||||
...
|
||||
...
|
||||
1
|
||||
4
|
||||
9
|
||||
@@ -133,8 +133,8 @@ Thus, if you try another for-loop, you get nothing:
|
||||
```python
|
||||
>>> for n in squares:
|
||||
... print(n)
|
||||
...
|
||||
>>>
|
||||
...
|
||||
>>>
|
||||
```
|
||||
|
||||
### Exercise 6.14: Generator Expressions in Function Arguments
|
||||
@@ -180,4 +180,4 @@ Modify the `ticker.py` program to use generator expressions
|
||||
as appropriate.
|
||||
|
||||
|
||||
[Contents](../Contents) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview)
|
||||
[Contents](../Contents.md) \| [Previous (6.3 Producer/Consumer)](03_Producers_consumers.md) \| [Next (7 Advanced Topics)](../07_Advanced_Topics/00_Overview.md)
|
||||
|
||||
@@ -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 seek more advanced material to fill out details.
|
||||
|
||||
* [7.1 Variable argument functions](01_Variable_arguments)
|
||||
* [7.2 Anonymous functions and lambda](02_Anonymous_function)
|
||||
* [7.3 Returning function and closures](03_Returning_functions)
|
||||
* [7.4 Function decorators](04_Function_decorators)
|
||||
* [7.5 Static and class methods](05_Decorated_methods)
|
||||
* [7.1 Variable argument functions](01_Variable_arguments.md)
|
||||
* [7.2 Anonymous functions and lambda](02_Anonymous_function.md)
|
||||
* [7.3 Returning function and closures](03_Returning_functions.md)
|
||||
* [7.4 Function decorators](04_Function_decorators.md)
|
||||
* [7.5 Static and class methods](05_Decorated_methods.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
@@ -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.md) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function.md)
|
||||
|
||||
# 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):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: __init__() takes exactly 4 arguments (2 given)
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
This is easily fixed using `*data` instead. Try this:
|
||||
@@ -177,11 +177,11 @@ def read_portfolio(filename):
|
||||
name, shares, and price.
|
||||
'''
|
||||
with open(filename) as lines:
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
types=[str,int,float])
|
||||
|
||||
portfolio = [ Stock(d['name'], d['shares'], d['price'])
|
||||
portfolio = [ Stock(d['name'], d['shares'], d['price'])
|
||||
for d in portdicts ]
|
||||
return Portfolio(portfolio)
|
||||
```
|
||||
@@ -201,8 +201,8 @@ def read_portfolio(filename, **opts):
|
||||
name, shares, and price.
|
||||
'''
|
||||
with open(filename) as lines:
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
types=[str,int,float],
|
||||
**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.md) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function.md)
|
||||
@@ -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.md) \| [Next (7.3 Returning Functions)](03_Returning_functions.md)
|
||||
|
||||
# 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
|
||||
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.md) \| [Next (7.3 Returning Functions)](03_Returning_functions.md)
|
||||
|
||||
@@ -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.md) \| [Next (7.4 Decorators)](04_Function_decorators.md)
|
||||
|
||||
# 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
|
||||
|
||||
@@ -237,4 +237,4 @@ is often good.
|
||||
Rewrite the `Stock` class in the file `stock.py` so that it uses typed properties
|
||||
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.md) \| [Next (7.4 Decorators)](04_Function_decorators.md)
|
||||
|
||||
@@ -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.md) \| [Next (7.5 Decorated Methods)](05_Decorated_methods.md)
|
||||
|
||||
# 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.
|
||||
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.
|
||||
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.
|
||||
|
||||
## Exercises
|
||||
@@ -154,7 +154,7 @@ __main__.countdown : 0.076562
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
[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.md) \| [Next (7.5 Decorated Methods)](05_Decorated_methods.md)
|
||||
|
||||
@@ -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.md) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview.md)
|
||||
|
||||
# 7.5 Decorated Methods
|
||||
|
||||
@@ -123,8 +123,8 @@ def read_portfolio(filename, **opts):
|
||||
name, shares, and price.
|
||||
'''
|
||||
with open(filename) as lines:
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
types=[str,int,float],
|
||||
**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:
|
||||
|
||||
```python
|
||||
@@ -184,8 +184,8 @@ class Portfolio:
|
||||
@classmethod
|
||||
def from_csv(cls, lines, **opts):
|
||||
self = cls()
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
portdicts = fileparse.parse_csv(lines,
|
||||
select=['name','shares','price'],
|
||||
types=[str,int,float],
|
||||
**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`
|
||||
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.md) \| [Next (8 Testing and Debugging)](../08_Testing_debugging/00_Overview.md)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# 8. Overview
|
||||
|
||||
This section introduces a few basic topics related to testing,
|
||||
logging, and debugging.
|
||||
logging, and debugging.
|
||||
|
||||
* [8.1 Testing](01_Testing)
|
||||
* [8.2 Logging, error handling and diagnostics](02_Logging)
|
||||
* [8.3 Debugging](03_Debugging)
|
||||
* [8.1 Testing](01_Testing.md)
|
||||
* [8.2 Logging, error handling and diagnostics](02_Logging.md)
|
||||
* [8.3 Debugging](03_Debugging.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
|
||||
@@ -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.md) \| [Next (8.2 Logging)](02_Logging.md)
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
@@ -274,7 +274,7 @@ Once you're satisifed that it works, write additional unit tests that
|
||||
check for the following:
|
||||
|
||||
- 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.
|
||||
- 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'
|
||||
```
|
||||
|
||||
[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.md) \| [Next (8.2 Logging)](02_Logging.md)
|
||||
|
||||
@@ -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.md) \| [Next (8.3 Debugging)](03_Debugging.md)
|
||||
|
||||
# 8.2 Logging
|
||||
|
||||
@@ -131,7 +131,7 @@ uses logging doesn't have to worry about that.
|
||||
|
||||
### 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:
|
||||
|
||||
```python
|
||||
@@ -262,7 +262,7 @@ steps to see that:
|
||||
>>> a = report.read_portfolio('Data/missing.csv')
|
||||
WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23']
|
||||
WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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: ''
|
||||
WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
|
||||
DEBUG:fileparse:Row 7: Reason: invalid literal for int() with base 10: ''
|
||||
>>>
|
||||
>>>
|
||||
```
|
||||
|
||||
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.
|
||||
# Change settings here to adjust logging output as needed.
|
||||
# Change settings here to adjust logging output as needed.
|
||||
import logging
|
||||
logging.basicConfig(
|
||||
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
|
||||
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.md) \| [Next (8.3 Debugging)](03_Debugging.md)
|
||||
|
||||
@@ -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.md) \| [Next (9 Packages)](../09_Packages/00_Overview.md)
|
||||
|
||||
# 8.3 Debugging
|
||||
|
||||
@@ -158,4 +158,4 @@ For breakpoints location is one of the following.
|
||||
|
||||
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.md) \| [Next (9 Packages)](../09_Packages/00_Overview.md)
|
||||
|
||||
@@ -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
|
||||
away or manage dependencies.
|
||||
|
||||
* [9.1 Packages](01_Packages)
|
||||
* [9.2 Third Party Modules](02_Third_party)
|
||||
* [9.3 Giving your code to others](03_Distribution)
|
||||
* [9.1 Packages](01_Packages.md)
|
||||
* [9.2 Third Party Modules](02_Third_party.md)
|
||||
* [9.3 Giving your code to others](03_Distribution.md)
|
||||
|
||||
[Contents](../Contents)
|
||||
[Contents](../Contents.md)
|
||||
|
||||
@@ -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.md) \| [Next (9.2 Third Party Packages)](02_Third_party.md)
|
||||
|
||||
# 9.1 Packages
|
||||
|
||||
@@ -119,7 +119,7 @@ import fileparse # BREAKS. fileparse not found
|
||||
|
||||
### 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.
|
||||
|
||||
```python
|
||||
@@ -204,7 +204,7 @@ import sys
|
||||
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:
|
||||
|
||||
```
|
||||
@@ -375,7 +375,7 @@ Try running some of your prior scripts as a main program:
|
||||
shell % cd porty-app
|
||||
shell % python3 -m porty.report portfolio.csv prices.csv txt
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
@@ -408,7 +408,7 @@ can run it in that location:
|
||||
shell % cd porty-app
|
||||
shell % python3 print-report.py portfolio.csv prices.csv txt
|
||||
Name Shares Price Change
|
||||
---------- ---------- ---------- ----------
|
||||
---------- ---------- ---------- ----------
|
||||
AA 100 9.22 -22.98
|
||||
IBM 50 106.28 15.18
|
||||
CAT 150 35.46 -47.98
|
||||
@@ -441,4 +441,4 @@ porty-app/
|
||||
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.md) \| [Next (9.2 Third Party Packages)](02_Third_party.md)
|
||||
|
||||
@@ -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.md) \| [Next (9.3 Distribution)](03_Distribution.md)
|
||||
|
||||
# 9.2 Third Party Modules
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
directories, you will get an `ImportError` exception.
|
||||
directories, you will get an `ImportError` exception.
|
||||
|
||||
### 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.
|
||||
|
||||
### 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
|
||||
the same steps as above:
|
||||
|
||||
```python
|
||||
>>> import numpy
|
||||
<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
|
||||
@@ -114,7 +114,7 @@ For example:
|
||||
For the purposes of experimenting and trying out different
|
||||
packages, a virtual environment will usually work fine. If,
|
||||
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.
|
||||
|
||||
### 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
|
||||
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.md) \| [Next (9.3 Distribution)](03_Distribution.md)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ information, you'll need to consult the [Python Packaging User Guide](https://pa
|
||||
|
||||
### 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
|
||||
# setup.py
|
||||
@@ -20,7 +20,7 @@ setuptools.setup(
|
||||
author="Your Name",
|
||||
author_email="you@example.com",
|
||||
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
|
||||
that you can now give away to others.
|
||||
that you can now give away to others.
|
||||
|
||||
### 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
|
||||
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`.
|
||||
|
||||
As a final step, see if you can install your package into a Python
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
or on Twitter at [@dabeaz](https://twitter.com/dabeaz). - David Beazley.
|
||||
|
||||
[Contents](../Contents) \| [Home](../..)
|
||||
[Contents](../Contents.md) \| [Home](../..)
|
||||
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [0. Course Setup (READ FIRST!)](00_Setup)
|
||||
* [1. Introduction to Python](01_Introduction/00_Overview)
|
||||
* [2. Working with Data](02_Working_with_data/00_Overview)
|
||||
* [3. Program Organization](03_Program_organization/00_Overview)
|
||||
* [4. Classes and Objects](04_Classes_objects/00_Overview)
|
||||
* [5. The Inner Workings of Python Objects](05_Object_model/00_Overview)
|
||||
* [6. Generators](06_Generators/00_Overview)
|
||||
* [7. A Few Advanced Topics](07_Advanced_Topics/00_Overview)
|
||||
* [8. Testing, Logging, and Debugging](08_Testing_debugging/00_Overview)
|
||||
* [9. Packages](09_Packages/00_Overview)
|
||||
* [0. Course Setup (READ FIRST!)](00_Setup.md)
|
||||
* [1. Introduction to Python](01_Introduction/00_Overview.md)
|
||||
* [2. Working with Data](02_Working_with_data/00_Overview.md)
|
||||
* [3. Program Organization](03_Program_organization/00_Overview.md)
|
||||
* [4. Classes and Objects](04_Classes_objects/00_Overview.md)
|
||||
* [5. The Inner Workings of Python Objects](05_Object_model/00_Overview.md)
|
||||
* [6. Generators](06_Generators/00_Overview.md)
|
||||
* [7. A Few Advanced Topics](07_Advanced_Topics/00_Overview.md)
|
||||
* [8. Testing, Logging, and Debugging](08_Testing_debugging/00_Overview.md)
|
||||
* [9. Packages](09_Packages/00_Overview.md)
|
||||
|
||||
[Home](..)
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -53,20 +53,20 @@ in some other programming language or Python itself.
|
||||
|
||||
This is not a course on web development. That's a different
|
||||
circus. However, if you stick around for this circus, you'll still see
|
||||
some interesting acts--just nothing involving animals.
|
||||
some interesting acts--just nothing involving animals.
|
||||
|
||||
This is not a course for software engineers on how to write or
|
||||
maintain a one-million line Python application. I don't write programs
|
||||
like that, nor do most companies who use Python, and neither should
|
||||
you. Delete something already!
|
||||
you. Delete something already!
|
||||
|
||||
## Take me to the Course Already!
|
||||
|
||||
Ok, ok. Point your browser [HERE](Notes/Contents)!
|
||||
Ok, ok. Point your browser [HERE](Notes/Contents.md)!
|
||||
|
||||
## Community Discussion
|
||||
|
||||
Want to discuss the course? You can join the conversation on
|
||||
Want to discuss the course? You can join the conversation on
|
||||
[Gitter](https://gitter.im/dabeaz-course/practical-python). I can't
|
||||
promise an individual response, but perhaps others can jump in to help.
|
||||
|
||||
@@ -94,7 +94,7 @@ No. This course is about you writing Python code, not watching someone else.
|
||||
|
||||
### Q: How is this course licensed?
|
||||
|
||||
Practical Python Programming is licensed under a Creative Commons Attribution ShareAlike 4.0 International License.
|
||||
Practical Python Programming is licensed under a Creative Commons Attribution ShareAlike 4.0 International License.
|
||||
|
||||
### Q: May I use this material to teach my own Python course?
|
||||
|
||||
@@ -116,5 +116,5 @@ cover it in the first place.
|
||||
Bug reports are appreciated and may be filed through the [issue
|
||||
tracker](https://github.com/dabeaz-course/practical-python/issues).
|
||||
Pull requests are not accepted except by invitation. Please file an
|
||||
issue first.
|
||||
issue first.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user