This commit is contained in:
David Beazley
2020-05-27 21:13:24 -05:00
parent 5c663c8b19
commit f9717a12c6
5 changed files with 110 additions and 73 deletions

View File

@@ -326,6 +326,15 @@ Oops! That's not what you wanted. Fix it so that the `symbols` variable holds t
>>> >>>
``` ```
Add `'HPQ'` to the front the string:
```python
>>> symbols = ?
>>> symbols
'HPQ,AAPL,IBM,MSFT,YHOO,SCO,GOOG'
>>>
```
In these examples, it might look like the original string is being In these examples, it might look like the original string is being
modified, in an apparent violation of strings being read only. Not modified, in an apparent violation of strings being read only. Not
so. Operations on strings create an entirely new string each so. Operations on strings create an entirely new string each

View File

@@ -1,8 +1,12 @@
[Contents](../Contents) \| [Previous (1.4 Strings)](04_Strings) \| [Next (1.6 Files)](06_Files)
# 1.5 Lists # 1.5 Lists
This section introduces lists, Python's primary type for holding an ordered collection of values.
### Creating a List ### Creating a List
Use square brackets to define a list: Use square brackets to define a list literal:
```python ```python
names = [ 'Elwood', 'Jake', 'Curtis' ] names = [ 'Elwood', 'Jake', 'Curtis' ]
@@ -12,7 +16,7 @@ nums = [ 39, 38, 42, 65, 111]
Sometimes lists are created by other methods. For example, a string can be split into a Sometimes lists are created by other methods. For example, a string can be split into a
list using the `split()` method: list using the `split()` method:
```pycon ```python
>>> line = 'GOOG,100,490.10' >>> line = 'GOOG,100,490.10'
>>> row = line.split(',') >>> row = line.split(',')
>>> row >>> row
@@ -53,7 +57,7 @@ Negative indices count from the end.
names[-1] # 'Curtis' names[-1] # 'Curtis'
``` ```
You can change any item in the list. You can change any item in a list.
```python ```python
names[1] = 'Joliet Jake' names[1] = 'Joliet Jake'
@@ -83,7 +87,7 @@ s * 3 # [1, 2, 3, 1, 2, 3, 1, 2, 3]
### List Iteration and Search ### List Iteration and Search
Iterating over the list contents. Use `for` to iterate over the list contents.
```python ```python
for name in names: for name in names:
@@ -117,8 +121,9 @@ names.remove('Curtis')
del names[1] del names[1]
``` ```
Removing an item does not create a hole. Other items will move down to fill the space vacated. Removing an item does not create a hole. Other items will move down
If there are more than one occurrence of the element, `.remove()` will remove only the first occurrence. to fill the space vacated. If there are more than one occurrence of
the element, `remove()` will remove only the first occurrence.
### List Sorting ### List Sorting
@@ -137,11 +142,17 @@ s = ['foo', 'bar', 'spam']
s.sort() # ['bar', 'foo', 'spam'] s.sort() # ['bar', 'foo', 'spam']
``` ```
Use `sorted()` if you'd like to make a new list instead:
```python
t = sorted(s) # s unchanged, t holds sorted values
```
### Lists and Math ### Lists and Math
*Caution: Lists were not designed for math operations.* *Caution: Lists were not designed for math operations.*
```pycon ```python
>>> nums = [1, 2, 3, 4, 5] >>> nums = [1, 2, 3, 4, 5]
>>> nums * 2 >>> nums * 2
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5] [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
@@ -149,7 +160,7 @@ s.sort() # ['bar', 'foo', 'spam']
[1, 2, 3, 4, 5, 10, 11, 12, 13, 14] >>> [1, 2, 3, 4, 5, 10, 11, 12, 13, 14] >>>
``` ```
Specifically, lists don't represent vectors/matrices as in MATLAB, Octave, IDL, etc. Specifically, lists don't represent vectors/matrices as in MATLAB, Octave, R, etc.
However, there are some packages to help you with that (e.g. [numpy](https://numpy.org)). However, there are some packages to help you with that (e.g. [numpy](https://numpy.org)).
## Exercises ## Exercises
@@ -157,13 +168,13 @@ However, there are some packages to help you with that (e.g. [numpy](https://num
In this exercise, we experiment with Python's list datatype. In the last section, In this exercise, we experiment with Python's list datatype. In the last section,
you worked with strings containing stock symbols. you worked with strings containing stock symbols.
```pycon ```python
>>> symbols = 'HPQ,AAPL,IBM,MSFT,YHOO,DOA,GOOG' >>> symbols = 'HPQ,AAPL,IBM,MSFT,YHOO,DOA,GOOG'
``` ```
Split it into a list of names using the `split()` operation of strings: Split it into a list of names using the `split()` operation of strings:
```pycon ```python
>>> symlist = symbols.split(',') >>> symlist = symbols.split(',')
``` ```
@@ -228,7 +239,7 @@ For instance, in the above example, the last two items of `symlist` got replaced
The `for` loop works by looping over data in a sequence such as a list. The `for` loop works by looping over data in a sequence such as a list.
Check this out by typing the following loop and watching what happens: Check this out by typing the following loop and watching what happens:
```pycon ```python
>>> for s in symlist: >>> for s in symlist:
print('s =', s) print('s =', s)
# Look at the output # Look at the output
@@ -238,7 +249,7 @@ Check this out by typing the following loop and watching what happens:
Use the `in` or `not in` operator to check if `'AIG'`,`'AA'`, and `'CAT'` are in the list of symbols. Use the `in` or `not in` operator to check if `'AIG'`,`'AA'`, and `'CAT'` are in the list of symbols.
```pycon ```python
>>> # Is 'AIG' IN the `symlist`? >>> # Is 'AIG' IN the `symlist`?
True True
>>> # Is 'AA' IN the `symlist`? >>> # Is 'AA' IN the `symlist`?
@@ -252,7 +263,7 @@ True
Use the `append()` method to add the symbol `'RHT'` to end of `symlist`. Use the `append()` method to add the symbol `'RHT'` to end of `symlist`.
```pycon ```python
>>> # append 'RHT' >>> # append 'RHT'
>>> symlist >>> symlist
['HPQ', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT'] ['HPQ', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT']
@@ -261,7 +272,7 @@ Use the `append()` method to add the symbol `'RHT'` to end of `symlist`.
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.
```pycon ```python
>>> # Insert 'AA' as the second item in the list >>> # Insert 'AA' as the second item in the list
>>> symlist >>> symlist
['HPQ', 'AA', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT'] ['HPQ', 'AA', 'AAPL', 'AIG', 'MSFT', 'YHOO', 'GOOG', 'RHT']
@@ -270,7 +281,7 @@ Use the `insert()` method to insert the symbol `'AA'` as the second item in the
Use the `remove()` method to remove `'MSFT'` from the list. Use the `remove()` method to remove `'MSFT'` from the list.
```pycon ```python
>>> # Remove 'MSFT' >>> # Remove 'MSFT'
>>> symlist >>> symlist
['HPQ', 'AA', 'AAPL', 'AIG', 'YHOO', 'GOOG', 'RHT'] ['HPQ', 'AA', 'AAPL', 'AIG', 'YHOO', 'GOOG', 'RHT']
@@ -281,7 +292,7 @@ Append a duplicate entry for `'YHOO'` at the end of the list.
*Note: it is perfectly fine for a list to have duplicate values.* *Note: it is perfectly fine for a list to have duplicate values.*
```pycon ```python
>>> # Append 'YHOO' >>> # Append 'YHOO'
>>> symlist >>> symlist
['HPQ', 'AA', 'AAPL', 'AIG', 'YHOO', 'GOOG', 'RHT', 'YHOO'] ['HPQ', 'AA', 'AAPL', 'AIG', 'YHOO', 'GOOG', 'RHT', 'YHOO']
@@ -290,7 +301,7 @@ Append a duplicate entry for `'YHOO'` at the end of the list.
Use the `index()` method to find the first position of `'YHOO'` in the list. Use the `index()` method to find the first position of `'YHOO'` in the list.
```pycon ```python
>>> # Find the first index of 'YHOO' >>> # Find the first index of 'YHOO'
4 4
>>> symlist[4] >>> symlist[4]
@@ -300,7 +311,7 @@ Use the `index()` method to find the first position of `'YHOO'` in the list.
Count how many times `'YHOO'` is in the list: Count how many times `'YHOO'` is in the list:
```pycon ```python
>>> symlist.count('YHOO') >>> symlist.count('YHOO')
2 2
>>> >>>
@@ -308,7 +319,7 @@ Count how many times `'YHOO'` is in the list:
Remove the first occurrence of `'YHOO'`. Remove the first occurrence of `'YHOO'`.
```pycon ```python
>>> # Remove first occurrence 'YHOO' >>> # Remove first occurrence 'YHOO'
>>> symlist >>> symlist
['HPQ', 'AA', 'AAPL', 'AIG', 'GOOG', 'RHT', 'YHOO'] ['HPQ', 'AA', 'AAPL', 'AIG', 'GOOG', 'RHT', 'YHOO']
@@ -322,7 +333,7 @@ However, we'll see an elegant way to do this in section 2.
Want to sort a list? Use the `sort()` method. Try it out: Want to sort a list? Use the `sort()` method. Try it out:
```pycon ```python
>>> symlist.sort() >>> symlist.sort()
>>> symlist >>> symlist
['AA', 'AAPL', 'AIG', 'GOOG', 'HPQ', 'RHT', 'YHOO'] ['AA', 'AAPL', 'AIG', 'GOOG', 'HPQ', 'RHT', 'YHOO']
@@ -331,7 +342,7 @@ Want to sort a list? Use the `sort()` method. Try it out:
Want to sort in reverse? Try this: Want to sort in reverse? Try this:
```pycon ```python
>>> symlist.sort(reverse=True) >>> symlist.sort(reverse=True)
>>> symlist >>> symlist
['YHOO', 'RHT', 'HPQ', 'GOOG', 'AIG', 'AAPL', 'AA'] ['YHOO', 'RHT', 'HPQ', 'GOOG', 'AIG', 'AAPL', 'AA']
@@ -345,7 +356,7 @@ Note: Sorting a list modifies its contents 'in-place'. That is, the elements of
Want to take a list of strings and join them together into one string? Want to take a list of strings and join them together into one string?
Use the `join()` method of strings like this (note: this looks funny at first). Use the `join()` method of strings like this (note: this looks funny at first).
```pycon ```python
>>> a = ','.join(symlist) >>> a = ','.join(symlist)
>>> a >>> a
'YHOO,RHT,HPQ,GOOG,AIG,AAPL,AA' 'YHOO,RHT,HPQ,GOOG,AIG,AAPL,AA'
@@ -363,7 +374,7 @@ Use the `join()` method of strings like this (note: this looks funny at first).
Lists can contain any kind of object, including other lists (e.g., nested lists). Lists can contain any kind of object, including other lists (e.g., nested lists).
Try this out: Try this out:
```pycon ```python
>>> nums = [101, 102, 103] >>> nums = [101, 102, 103]
>>> items = ['spam', symlist, nums] >>> items = ['spam', symlist, nums]
>>> items >>> items
@@ -375,7 +386,7 @@ The first element is a string, but the other two elements are lists.
You can access items in the nested lists by using multiple indexing operations. You can access items in the nested lists by using multiple indexing operations.
```pycon ```python
>>> items[0] >>> items[0]
'spam' 'spam'
>>> items[0][0] >>> items[0][0]

View File

@@ -1,5 +1,9 @@
[Contents](../Contents) \| [Previous (1.5 Lists)](05_Lists) \| [Next (1.7 Functions)](07_Functions)
# 1.6 File Management # 1.6 File Management
Most programs need to read input from somewhere. This section discusses file access.
### File Input and Output ### File Input and Output
Open a file. Open a file.
@@ -9,7 +13,7 @@ f = open('foo.txt', 'rt') # Open for reading (text)
g = open('bar.txt', 'wt') # Open for writing (text) g = open('bar.txt', 'wt') # Open for writing (text)
``` ```
Reading data. Read all of the data.
```python ```python
data = f.read() data = f.read()
@@ -18,7 +22,7 @@ data = f.read()
data = f.read([maxbytes]) data = f.read([maxbytes])
``` ```
Writing text to a file. Write some text.
```python ```python
g.write('some text') g.write('some text')
@@ -31,11 +35,12 @@ f.close()
g.close() g.close()
``` ```
Files should be properly closed. This is why the preferred approach is to use the `with` statement. Files should be properly closed and it's an easy step to forget.
Thus, the preferred approach is to use the `with` statement like this.
```python ```python
with open(filename, 'rt') as f: with open(filename, 'rt') as file:
# Use the file `f` # Use the file `file`
... ...
# No need to close explicitly # No need to close explicitly
...statements ...statements
@@ -45,61 +50,63 @@ This automatically closes the file when control leaves the indented code block.
### Common Idioms for Reading File Data ### Common Idioms for Reading File Data
Reading an entire file all at once as a string. Read an entire file all at once as a string.
```python ```python
with open('foo.txt', 'rt') as f: with open('foo.txt', 'rt') as file:
data = f.read() data = file.read()
# `data` is a string with all the text in `foo.txt` # `data` is a string with all the text in `foo.txt`
``` ```
Reading a file line-by-line Read a file line-by-line by iterating.
```python ```python
with open(filename, 'rt') as f: with open(filename, 'rt') as file:
for line in f: for line in file:
# Process the line `f` # Process the line
``` ```
Writing string data. ### Common Idioms for Write to a File
Write string data.
```python ```python
with open('outfile', 'wt') as f: with open('outfile', 'wt') as out:
f.write('Hello World\n') out.write('Hello World\n')
... ...
``` ```
Redirecting the print function. Redirect the print function.
```python ```python
with open('outfile', 'wt') as f: with open('outfile', 'wt') as out:
print('Hello World', file=f) print('Hello World', file=out)
... ...
``` ```
## Exercises ## Exercises
This exercise depends on a file `Data/portfolio.csv`. The file contains a list of lines with information on a portfolio of stocks. These exercises depend on a file `Data/portfolio.csv`. The file
Locate the file and look at its contents: contains a list of lines with information on a portfolio of stocks.
It is assumed that you are working in the `practical-python/Work/`
directory. If you're not sure, you can find out where Python thinks
it's running by doing this:
### Exercise 1.26: File Preliminaries ```python
*Note: Make sure you are running Python in a location where you can access the `portfolio.csv` file.
It's normally located in `Data/portfolio.csv`.
You can find out where Python thinks it's running by doing this:
```pycon
>>> import os >>> import os
>>> os.getcwd() >>> os.getcwd()
'/Users/beazley/Desktop/practical-python' # Output vary '/Users/beazley/Desktop/practical-python/Work' # Output vary
>>> >>>
``` ```
### Exercise 1.26: File Preliminaries
First, try reading the entire file all at once as a big string: First, try reading the entire file all at once as a big string:
```pycon ```python
>>> with open('Data/portfolio.csv', 'rt') as f: >>> with open('Data/portfolio.csv', 'rt') as f:
data = f.read() data = f.read()
>>> data >>> data
'name,shares,price\n"AA",100,32.20\n"IBM",50,91.10\n"CAT",150,83.44\n"MSFT",200,51.23\n"GE",95,40.37\n"MSFT",50,65.10\n"IBM",100,70.44\n' 'name,shares,price\n"AA",100,32.20\n"IBM",50,91.10\n"CAT",150,83.44\n"MSFT",200,51.23\n"GE",95,40.37\n"MSFT",50,65.10\n"IBM",100,70.44\n'
>>> print(data) >>> print(data)
@@ -127,10 +134,11 @@ time.
To read a file line-by-line, use a for-loop like this: To read a file line-by-line, use a for-loop like this:
```pycon ```python
>>> with open('Data/portfolio.csv', 'rt') as f: >>> with open('Data/portfolio.csv', 'rt') as f:
for line in f: for line in f:
print(line, end='') print(line, end='')
name,shares,price name,shares,price
"AA",100,32.20 "AA",100,32.20
"IBM",50,91.10 "IBM",50,91.10
@@ -145,7 +153,7 @@ On certain occasions, you might want to manually read or skip a
*single* line of text (e.g., perhaps you want to skip the first line *single* line of text (e.g., perhaps you want to skip the first line
of column headers). of column headers).
```pycon ```python
>>> f = open('Data/portfolio.csv', 'rt') >>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f) >>> headers = next(f)
>>> headers >>> headers
@@ -167,7 +175,7 @@ Thus, you normally wouldnt call it directly unless youre trying to explici
Once youre reading lines of a file, you can start to perform more processing such as splitting. Once youre reading lines of a file, you can start to perform more processing such as splitting.
For example, try this: For example, try this:
```pycon ```python
>>> f = open('Data/portfolio.csv', 'rt') >>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f).split(',') >>> headers = next(f).split(',')
>>> headers >>> headers
@@ -189,7 +197,7 @@ For example, try this:
Now that you know how to read a file, lets write a program to perform a simple calculation. Now that you know how to read a file, lets write a program to perform a simple calculation.
The columns in `portfolio.csv` correspond to the stock name, number of The columns in `portfolio.csv` correspond to the stock name, number of
shares, and purchase price of a single share. Write a program called shares, and purchase price of a single stock holding. Write a program called
`pcost.py` that opens this file, reads all lines, and calculates how `pcost.py` that opens this file, reads all lines, and calculates how
much it cost to purchase all of the shares in the portfolio. much it cost to purchase all of the shares in the portfolio.
@@ -201,7 +209,7 @@ Your program should print output such as the following:
Total cost 44671.15 Total cost 44671.15
``` ```
### Exercise 1.28: Other kinds of 'files' ### Exercise 1.28: Other kinds of "files"
What if you wanted to read a non-text file such as a gzip-compressed What if you wanted to read a non-text file such as a gzip-compressed
datafile? The builtin `open()` function wont help you here, but datafile? The builtin `open()` function wont help you here, but
@@ -210,7 +218,7 @@ files.
Try it: Try it:
```pycon ```python
>>> import gzip >>> import gzip
>>> with gzip.open('Data/portfolio.csv.gz') as f: >>> with gzip.open('Data/portfolio.csv.gz') as f:
for line in f: for line in f:

View File

@@ -1,7 +1,9 @@
[Contents](../Contents) \| [Previous (1.6 Files)](06_Files) \| [Next (2.0 Working with Data)](../02_Working_with_data/00_Overview)
# 1.7 Functions # 1.7 Functions
As your programs start to get larger, you'll want to get organized. This section As your programs start to get larger, you'll want to get organized. This section
introduces functions. Error handling with exceptions is also introduced. briefly introduces functions and library modules. Error handling with exceptions is also introduced.
### Custom Functions ### Custom Functions
@@ -19,10 +21,9 @@ def sumcount(n):
return total return total
``` ```
Calling a function. To call a function.
```python ```python
# Use parenthesis to call the function
a = sumcount(100) a = sumcount(100)
``` ```
@@ -33,13 +34,12 @@ The `return` keyword is needed to explicitly specify the return value of the fun
Python comes with a large standard library. Python comes with a large standard library.
Library modules are accessed using `import`. Library modules are accessed using `import`.
For example:
```python ```python
# `math` module
import math import math
x = math.sqrt(10) x = math.sqrt(10)
# `urllib.request` module
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,11 +49,12 @@ We will cover libraries and modules in more detail later.
### Errors and exceptions ### Errors and exceptions
Functions report errors as exceptions. An exception causes the program to stop. 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. Try this in your python REPL.
```pycon ```python
>>> int('N/A') >>> int('N/A')
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <module>
@@ -82,6 +83,12 @@ for line in f:
The name `ValueError` must match the kind of error you are trying to catch. The name `ValueError` must match the kind of error you are trying to catch.
It is often difficult to know exactly what kinds of errors might occur
in advance depending on the operation being performed. For better or
for worse, exception handling often gets added *after* a program has
unexpectedly crashed (i.e., "oh, we forgot to catch that error. We
should handle that!").
### Raising Exceptions ### Raising Exceptions
To raise an exception, use the `raise` statement. To raise an exception, use the `raise` statement.
@@ -104,7 +111,7 @@ RuntimeError: What a kerfuffle
### Exercise 1.29: Defining a function ### Exercise 1.29: Defining a function
You can define a simple function using the `def` statement. For example, Try defining a simple function:
```python ```python
>>> def greeting(name): >>> def greeting(name):
@@ -124,7 +131,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)
and turn it into a function `portfolio_cost(filename)`. The 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.
@@ -160,9 +167,11 @@ This will allow you to call your function from the interactive mode.
Being able to experiment with your code interactively is useful for Being able to experiment with your code interactively is useful for
testing and debugging. testing and debugging.
### Exercise 1.31: Error handling
What happens if you try your function on a file with some missing fields? What happens if you try your function on a file with some missing fields?
```pycon ```python
>>> portfolio_cost('Data/missing.csv') >>> portfolio_cost('Data/missing.csv')
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <module>
@@ -180,14 +189,14 @@ manner.
Modify the `pcost.py` program to catch the exception, print a warning Modify the `pcost.py` program to catch the exception, print a warning
message, and continue processing the rest of the file. message, and continue processing the rest of the file.
### Exercise 1.31: Using a library function ### Exercise 1.32: Using a library function
Python comes with a large standard library of useful functions. One Python comes with a large standard library of useful functions. One
library that might be useful here is the `csv` module. You should use library that might be useful here is the `csv` module. You should use
it whenever you have to work with CSV data files. Here is an example it whenever you have to work with CSV data files. Here is an example
of how it works: of how it works:
```pycon ```python
>>> import csv >>> import csv
>>> f = open('Data/portfolio.csv') >>> f = open('Data/portfolio.csv')
>>> rows = csv.reader(f) >>> rows = csv.reader(f)
@@ -216,7 +225,7 @@ away from the names in the first column.
Modify your `pcost.py` program so that it uses the `csv` module for Modify your `pcost.py` program so that it uses the `csv` module for
parsing and try running earlier examples. parsing and try running earlier examples.
### Exercise 1.32: Reading from the command line ### Exercise 1.33: Reading from the command line
In the `pcost.py` program, the name of the input file has been hardwired into the code: In the `pcost.py` program, the name of the input file has been hardwired into the code:
@@ -250,7 +259,7 @@ def portfolio_cost(filename):
if len(sys.argv) == 2: if len(sys.argv) == 2:
filename = sys.argv[1] filename = sys.argv[1]
else: else:
filename = 'portfolio.csv' filename = 'Data/portfolio.csv'
cost = portfolio_cost(filename) cost = portfolio_cost(filename)
print('Total cost:', cost) print('Total cost:', cost)