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
modified, in an apparent violation of strings being read only. Not
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
This section introduces lists, Python's primary type for holding an ordered collection of values.
### Creating a List
Use square brackets to define a list:
Use square brackets to define a list literal:
```python
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
list using the `split()` method:
```pycon
```python
>>> line = 'GOOG,100,490.10'
>>> row = line.split(',')
>>> row
@@ -53,7 +57,7 @@ Negative indices count from the end.
names[-1] # 'Curtis'
```
You can change any item in the list.
You can change any item in a list.
```python
names[1] = 'Joliet Jake'
@@ -83,7 +87,7 @@ s * 3 # [1, 2, 3, 1, 2, 3, 1, 2, 3]
### List Iteration and Search
Iterating over the list contents.
Use `for` to iterate over the list contents.
```python
for name in names:
@@ -117,8 +121,9 @@ names.remove('Curtis')
del names[1]
```
Removing an item does not create a hole. Other items will move down to fill the space vacated.
If there are more than one occurrence of the element, `.remove()` will remove only the first occurrence.
Removing an item does not create a hole. Other items will move down
to fill the space vacated. If there are more than one occurrence of
the element, `remove()` will remove only the first occurrence.
### List Sorting
@@ -137,11 +142,17 @@ s = ['foo', 'bar', '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
*Caution: Lists were not designed for math operations.*
```pycon
```python
>>> nums = [1, 2, 3, 4, 5]
>>> nums * 2
[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] >>>
```
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)).
## 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,
you worked with strings containing stock symbols.
```pycon
```python
>>> symbols = 'HPQ,AAPL,IBM,MSFT,YHOO,DOA,GOOG'
```
Split it into a list of names using the `split()` operation of strings:
```pycon
```python
>>> 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.
Check this out by typing the following loop and watching what happens:
```pycon
```python
>>> for s in symlist:
print('s =', s)
# 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.
```pycon
```python
>>> # Is 'AIG' IN the `symlist`?
True
>>> # Is 'AA' IN the `symlist`?
@@ -252,7 +263,7 @@ True
Use the `append()` method to add the symbol `'RHT'` to end of `symlist`.
```pycon
```python
>>> # append 'RHT'
>>> symlist
['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.
```pycon
```python
>>> # Insert 'AA' as the second item in the list
>>> symlist
['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.
```pycon
```python
>>> # Remove 'MSFT'
>>> symlist
['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.*
```pycon
```python
>>> # Append 'YHOO'
>>> symlist
['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.
```pycon
```python
>>> # Find the first index of 'YHOO'
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:
```pycon
```python
>>> symlist.count('YHOO')
2
>>>
@@ -308,7 +319,7 @@ Count how many times `'YHOO'` is in the list:
Remove the first occurrence of `'YHOO'`.
```pycon
```python
>>> # Remove first occurrence 'YHOO'
>>> symlist
['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:
```pycon
```python
>>> symlist.sort()
>>> symlist
['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:
```pycon
```python
>>> symlist.sort(reverse=True)
>>> symlist
['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?
Use the `join()` method of strings like this (note: this looks funny at first).
```pycon
```python
>>> a = ','.join(symlist)
>>> a
'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).
Try this out:
```pycon
```python
>>> nums = [101, 102, 103]
>>> items = ['spam', symlist, nums]
>>> 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.
```pycon
```python
>>> items[0]
'spam'
>>> 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
Most programs need to read input from somewhere. This section discusses file access.
### File Input and Output
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)
```
Reading data.
Read all of the data.
```python
data = f.read()
@@ -18,7 +22,7 @@ data = f.read()
data = f.read([maxbytes])
```
Writing text to a file.
Write some text.
```python
g.write('some text')
@@ -31,11 +35,12 @@ f.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
with open(filename, 'rt') as f:
# Use the file `f`
with open(filename, 'rt') as file:
# Use the file `file`
...
# No need to close explicitly
...statements
@@ -45,61 +50,63 @@ This automatically closes the file when control leaves the indented code block.
### 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
with open('foo.txt', 'rt') as f:
data = f.read()
with open('foo.txt', 'rt') as file:
data = file.read()
# `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
with open(filename, 'rt') as f:
for line in f:
# Process the line `f`
with open(filename, 'rt') as file:
for line in file:
# Process the line
```
Writing string data.
### Common Idioms for Write to a File
Write string data.
```python
with open('outfile', 'wt') as f:
f.write('Hello World\n')
with open('outfile', 'wt') as out:
out.write('Hello World\n')
...
```
Redirecting the print function.
Redirect the print function.
```python
with open('outfile', 'wt') as f:
print('Hello World', file=f)
with open('outfile', 'wt') as out:
print('Hello World', file=out)
...
```
## Exercises
This exercise depends on a file `Data/portfolio.csv`. The file contains a list of lines with information on a portfolio of stocks.
Locate the file and look at its contents:
These exercises depend on a file `Data/portfolio.csv`. The file
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
*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
```python
>>> import os
>>> 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:
```pycon
```python
>>> with open('Data/portfolio.csv', 'rt') as f:
data = f.read()
>>> 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'
>>> print(data)
@@ -127,10 +134,11 @@ time.
To read a file line-by-line, use a for-loop like this:
```pycon
```python
>>> with open('Data/portfolio.csv', 'rt') as f:
for line in f:
print(line, end='')
name,shares,price
"AA",100,32.20
"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
of column headers).
```pycon
```python
>>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f)
>>> 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.
For example, try this:
```pycon
```python
>>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f).split(',')
>>> 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.
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
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
```
### 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
datafile? The builtin `open()` function wont help you here, but
@@ -210,7 +218,7 @@ files.
Try it:
```pycon
```python
>>> import gzip
>>> with gzip.open('Data/portfolio.csv.gz') as 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
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
@@ -19,10 +21,9 @@ def sumcount(n):
return total
```
Calling a function.
To call a function.
```python
# Use parenthesis to call the function
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.
Library modules are accessed using `import`.
For example:
```python
# `math` module
import math
x = math.sqrt(10)
# `urllib.request` module
import urllib.request
u = urllib.request.urlopen('http://www.python.org/')
data = u.read()
@@ -49,11 +49,12 @@ We will cover libraries and modules in more detail later.
### 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.
```pycon
```python
>>> int('N/A')
Traceback (most recent call last):
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.
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
To raise an exception, use the `raise` statement.
@@ -104,7 +111,7 @@ RuntimeError: What a kerfuffle
### Exercise 1.29: Defining a function
You can define a simple function using the `def` statement. For example,
Try defining a simple function:
```python
>>> 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
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
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
testing and debugging.
### Exercise 1.31: Error handling
What happens if you try your function on a file with some missing fields?
```pycon
```python
>>> portfolio_cost('Data/missing.csv')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
@@ -180,14 +189,14 @@ manner.
Modify the `pcost.py` program to catch the exception, print a warning
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
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
of how it works:
```pycon
```python
>>> import csv
>>> f = open('Data/portfolio.csv')
>>> 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
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:
@@ -250,7 +259,7 @@ def portfolio_cost(filename):
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
filename = 'portfolio.csv'
filename = 'Data/portfolio.csv'
cost = portfolio_cost(filename)
print('Total cost:', cost)