Editing
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 wouldn’t call it directly unless you’re trying to explici
|
||||
Once you’re 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, let’s 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 won’t 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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user