Python

Try to master Python. Don’t merely try to learn enough to complete the problem sets or pass the exams. Your goal should be to become fluent in Python. In that regard, it is like learning French or Chinese. If you want to converse with native speakers, you need to learn more than the dialogs or exams.

Google Python Class

Introduction https://developers.google.com/edu/python/introduction

A non-exhaustive list of features which are only available in 3.x releases and won't be backported to the 2.x series:

if __name__ == '__main__':

main()



Strings https://developers.google.com/edu/python/strings

hello

world

“””

QUESTION: what is ‘hello’[:-1]


Lists https://developers.google.com/edu/python/lists

squares = [1, 4, 9, 16]

sum = 0

for num in squares:

sum += num

print sum ## 30


list = ['larry', 'curly', 'moe']

if 'curly' in list:

print 'yay'

i = 0

while i < len(a):

print a[i]

i = i + 3

Here are some other common list methods.

Sorting https://developers.google.com/edu/python/sorting

strs = ['ccc', 'aaaa', 'd', 'bb']

print sorted(strs, key=len) ## ['d', 'bb', 'ccc', 'aaaa']


## "key" argument specifying str.lower function to use for sorting

print sorted(strs, key=str.lower) ## ['aa', 'BB', 'CC', 'zz']

def MyFn(s):

return s[-1]


## Now pass key=MyFn to sorted() to sort by the last letter:

print sorted(strs, key=MyFn) ## ['wa', 'zb', 'xc', 'yd']

nums = [1, 2, 3, 4]

squares = [ n * n for n in nums ] ## [1, 4, 9, 16]


strs = ['hello', 'and', 'goodbye']

shouting = [ s.upper() + '!!!' for s in strs ]

## ['HELLO!!!', 'AND!!!', 'GOODBYE!!!']

## Select values <= 2

nums = [2, 8, 1, 6]

small = [ n for n in nums if n <= 2 ] ## [2, 1]

## Select fruits containing 'a', change to upper case

fruits = ['apple', 'cherry', 'bannana', 'lemon']

afruits = [ s.upper() for s in fruits if 'a' in s ]

## ['APPLE', 'BANNANA']


Dicts and Files https://developers.google.com/edu/python/dict-files


dict = {}

dict['a'] = 'alpha'

dict['g'] = 'gamma'

dict['o'] = 'omega'


print dict ## {'a': 'alpha', 'o': 'omega', 'g': 'gamma'}


print dict['a'] ## Simple lookup, returns 'alpha'

dict['a'] = 6 ## Put new key/value into dict

'a' in dict ## True

## print dict['z'] ## Throws KeyError

if 'z' in dict: print dict['z'] ## Avoid KeyError

print dict.get('z') ## None (instead of KeyError)



## By default, iterating over a dict iterates over its keys.

## Note that the keys are in a random order.

for key in dict: print key

## prints a g o


## Exactly the same as above

for key in dict.keys(): print key


## Get the .keys() list:

print dict.keys() ## ['a', 'o', 'g']


## Likewise, there's a .values() list of values

print dict.values() ## ['alpha', 'omega', 'gamma']


## Common case -- loop over the keys in sorted order,

## accessing each key/value

for key in sorted(dict.keys()):

print key, dict[key]


## .items() is the dict expressed as (key, value) tuples

print dict.items() ## [('a', 'alpha'), ('o', 'omega'), ('g', 'gamma')]


## This loop syntax accesses the whole dict by looping

## over the .items() tuple list, accessing one (key, value)

## pair on each iteration.

for k, v in dict.items(): print k, '>', v

## a > alpha o > omega g > gamma


var = 6

del var # var no more!

list = ['a', 'b', 'c', 'd']

del list[0] ## Delete first element

del list[-2:] ## Delete last two elements

print list ## ['b']


dict = {'a':1, 'b':2, 'c':3}

del dict['b'] ## Delete 'b' entry

print dict ## {'a':1, 'c':3}



# Echo the contents of a file

f = open('foo.txt', 'rU') ## U = Universal mode, which is smart about end of lines

for line in f: ## iterates over the lines of the file

print line, ## trailing , so print does not add an end-of-line char

## since 'line' already includes the end-of line.

f.close()






Regular Expressions https://developers.google.com/edu/python/regular-expressions

import re

match = re.search(pat, str)


str = 'an example word:cat!!'

match = re.search(r'word:\w\w\w', str)

# If-statement after search() tests if it succeeded

if match:

print 'found', match.group() ## 'found word:cat'

else:

print 'did not find'

The power of regular expressions is that they can specify patterns, not just fixed characters. Here are the most basic patterns which match single chars:

Repetition

Things get more interesting when you use + and * to specify repetition in the pattern

Leftmost & Largest

First the search finds the leftmost match for the pattern, and second it tries to use up as much of the string as possible -- i.e. + and * go as far as possible (the + and * are said to be "greedy").

Examples

## i+ = one or more i's, as many as possible.

match = re.search(r'pi+', 'piiig') => found, match.group() == "piii"


## Finds the first/leftmost solution, and within it drives the +

## as far as possible (aka 'leftmost and largest').

## In this example, note that it does not get to the second set of i's.

match = re.search(r'i+', 'piigiiii') => found, match.group() == "ii"


## \s* = zero or more whitespace chars

## Here look for 3 digits, possibly separated by whitespace.

match = re.search(r'\d\s*\d\s*\d', 'xx1 2 3xx') => found, match.group() == "1 2 3"

match = re.search(r'\d\s*\d\s*\d', 'xx12 3xx') => found, match.group() == "12 3"

match = re.search(r'\d\s*\d\s*\d', 'xx123xx') => found, match.group() == "123"


## ^ = matches the start of string, so this fails:

match = re.search(r'^b\w+', 'foobar') => not found, match == None

## but without the ^ it succeeds:

match = re.search(r'b\w+', 'foobar') => found, match.group() == "bar"


Options

The re functions take options to modify the behavior of the pattern match. The option flag is added as an extra argument to the search() or findall() etc., e.g. re.search(pat, str, re.IGNORECASE).

Other


Utilities https://developers.google.com/edu/python/utilities

File System -- os, os.path, shutil

The *os* and *os.path* modules include many functions to interact with the file system. The *shutil* module can copy files.

Running External Processes -- commands

The *commands* module is a simple way to run an external command and capture its output.

Exceptions

An exception represents a run-time error that halts the normal execution at a particular line and transfers control to error handling code. This section just introduces the most basic uses of exceptions. For example a run-time error might be that a variable used in the program does not have a value (ValueError .. you've probably seen that one a few times), or a file open operation error because that a does not exist (IOError). (See [[http://docs.python.org/tut/node10.html][exception docs]])

Without any error handling code (as we have done thus far), a run-time exception just halts the program with an error message. That's a good default behavior, and you've seen it many times. You can add a "try/except" structure to your code to handle exceptions, like this:

try:

## Either of these two lines could throw an IOError, say

## if the file does not exist or the read() encounters a low level error.

f = open(filename, 'rU')

text = f.read()

f.close()

except IOError:

## Control jumps directly to here if any of the above lines throws IOError.

sys.stderr.write('problem reading:' + filename)

## In any case, the code then continues with the line after the try/except

The try: section includes the code which might throw an exception. The except: section holds the code to run if there is an exception. If there is no exception, the except: section is skipped (that is, that code is for error handling only, not the "normal" case for the code). You can get a pointer to the exception object itself with syntax "except IOError, e: .. (e points to the exception object)".

HTTP -- urllib and urlparse

The module *urllib* provides url fetching -- making a url look like a file you can read form. The *urlparse* module can take apart and put together urls.

## Given a url, try to retrieve it. If it's text/html,

## print its base url and its text.

def wget(url):

ufile = urllib.urlopen(url) ## get file-like object for url

info = ufile.info() ## meta-info about the url content

if info.gettype() == 'text/html':

print 'base url:' + ufile.geturl()

text = ufile.read() ## read all its text

print text

The above code works fine, but does not include error handling if a url does not work for some reason. Here's a version of the function which adds try/except logic to print an error message if the url operation fails.

## Version that uses try/except to print an error message if the

## urlopen() fails.

def wget2(url):

try:

ufile = urllib.urlopen(url)

if ufile.info().gettype() == 'text/html':

print ufile.read()

except IOError:

print 'problem reading url:', url






Python3: urllib.request module

See f0210.py
  try:
    ufile = urllib.request.urlopen(url)
    print (ufile.read())
  except IOError:
      return ('problem reading url:' + url)

Homework 0



Homework 1


Homework 2



Python notes



Hierarchy


Built in objects = type() strive for polymorphism


String encodings


Numbers


Garbage collection


Files


recursion

1