1 of 53

Introduction to Python

Dr. Mike Murphy

Dr. Sebastien Goasguen

CPSC 362 -- Distributed Computing

CSCI 410 -- Operating Systems

Fall 2010, Based on Python 2.6 (Fedora/Arch Linux)

2 of 53

License

This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

3 of 53

Python Language

  • Interpreted (background bytecode-compiled)‏
  • Object-Oriented
  • Dynamically Typed
  • Rapid Prototyping and Development
  • Compact Code
  • Easy to Learn

4 of 53

Origin of the Name

5 of 53

Code Structure

  • Blocks defined by indentation (no curly braces)‏
  • Statements end at newline character, can be continued to trailing line by ending current line with a backslash (\)‏
  • No semicolons at end of lines, but semicolons can be used to put multiple statements on the same line

6 of 53

Running the Interpreter

  • Run the “python” command without arguments to run in interactive mode
    • Use CTRL+D (CTRL+Z on Windows) to exit
  • Run a script by passing the script filename as first argument to “python” command
  • On Unix, run a script directly by making it executable (only works if “#!/usr/bin/env python” is the top line of the file)‏

7 of 53

Basic Form of a Script

#!/usr/bin/env python

# Comments start with the # symbol and run to the end of the current line

print 'Hello, World'

print '''Strings that

span multiple lines are both possible and

fun'''

print “Double-quoted string to say goodbye”

8 of 53

If-Else Statements

if something == something_else:

    do_something()‏

    do_another_something()‏

else:

    do_something_else()‏

if something == something_else or something != 42:

    do_yet_another_thing()‏

elif otherwise_happy:

    print 'yay!'

9 of 53

Loops

mylist = [1, 2, 3, 4, 5, 6, 7]

for elt in mylist:

    print str(elt) + ' is ', # trailing comma suppresses newline

    if elt % 2 != 0:

        print 'uneven'

    else:

        print 'not odd'

while True:

    print 'Infinite'

10 of 53

Basic Data Types

  • Numbers
    • Integers (and arbitrary-precision long ints)‏
    • Floating-point (double-precision)
  • Strings
    • Immutable – you cannot change a string in place (e.g. mystr[2] = 'c' causes an exception)‏
    • Can be single, double, or triple quoted, as long as you're consistent (triple-quoted can be multi-line)‏

11 of 53

Numeric Operations

x = 10

y = 20

z = 3.14159265358979323846

print x * y

print x ** 2

print y / z

12 of 53

String Methods

my_str = 'Hello, World'

print my_str[2]

print my_str[2:7]

print my_str[2:-1]

print my_str[-1]

print my_str[5].isalpha()‏

print my_str[6].isspace()‏

print my_str.split(',')‏

13 of 53

String Substitutions

x = 10

y = 20

z = 'Hello'

print 'x is %d and y is %d' % (x, y)‏

print 'z is %s' % z

print 'x is', x

print 'x is ' + x # ERROR: can't concatenate str and int

print 'x is ' + str(x)‏

print 'x is %d' % x

14 of 53

Basic Data Types

  • Lists
    • Mutable sequence types
    • Completely dynamic (contrast to C/Java arrays)‏
  • Dictionaries
    • Mapping types
  • Tuples
    • Immutable

15 of 53

List Operations

mylist = [1, 5, 6, 9, 2, 4, 10, 3, 8, 7]

mylist.append(11)‏

mylist.sort() # sorts IN PLACE (returns None)‏

first_3_elems = mylist[0:3] # Slice operation

last_3_elems = mylist[-3:] # Negative numbers: count from end

copy_of_mylist = mylist[:] # Shallow element copy

another_ref = mylist # Copy of the reference (pointer) ONLY!

another_ref[2] = 42 # changes the original list!

16 of 53

List Comprehensions

some_ints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

even = [ x for x in some_ints if x % 2 == 0 ]

oddnot3 = [ y for y in some_ints if y % 2 != 0 and y != 3 ]

17 of 53

Dictionaries

mymap = { 'key1' : 'value1', 'key2' : 'value2' }

print mymap['key2']

for key in mymap:

    print key, mymap[key]

del mymap['key1']

18 of 53

Tuples

# Immutable: more efficient than lists for some operations

mytup = (1, 2, 3)‏

# Multiple assignment:

a, b, c = mytup

# Implicit tuples:

x, y, z = 4, 5, 6

19 of 53

File I/O

  • Bound to underlying C library at a low level
    • But without all the buffer malloc'ing and pointer nonsense
  • File object created upon opening a file
  • Variables reference file objects (pointers)‏

20 of 53

File Copy Example

#!/usr/bin/env python

import sys

srcfile = open(sys.argv[1], 'r')‏

dstfile = open(sys.argv[2], 'w')‏

dstfile.write(srcfile.read())‏

srcfile.close()‏

dstfile.close()‏

21 of 53

Data Type Documentation

  • Look in the “Library Reference” for the appropriate Python version
  • http://docs.python.org/

22 of 53

Functions

  • Implicit return types
    • Return types vary depending on type of variable returned
    • Can return multiple values by returning a tuple
  • No type specification for arguments
  • Default types possible
  • Arguments in function calls can be in order (like C), or explicitly named

23 of 53

Function Example

def add(a, b):

    return a + b

print add(1, 2)‏

print add(1.0, 3.14)‏

print add('Hello ', 'World')‏

print add('Hello ', 2) # throws an exception

24 of 53

Named and Default Parameters

def make_cone(start_x = 8.0, start_y = 8.0, radius = 4.0, height = 3.2):

    pass # do nothing: this is a stub (implementation not important)‏

make_cone() # defaults: 8, 8, 4, 3.2

make_cone(10) # start_x 10, others default

make_cone(radius = 2.0) # radius 2, others default

make_cone(radius = 2.0, height = 1.5, start_y = 3.5, start_x = 0)‏

25 of 53

Sequence Expansion

def make_cone(start_x = 8.0, start_y = 8.0, radius = 4.0, height = 3.2):

    pass # do nothing: this is a stub (implementation not important)‏

first_cone = (3.5, 2.9, 5.2, 11.6)‏

second_cone = [10.0, 12.0, 4.0, 2.2]

make_cone(*first_cone)‏

make_cone(*second_cone)‏

26 of 53

Fun With Function Parameters

def happy(*args, **kwds):

    for arg in args:

        print arg

    for kwd in kwds:

        print kwd, '=', kwds[kwd]

print happy()‏

print happy(1, 2, 3)‏

print happy(1, 2, 3, foo='bar', bar='foobar')‏

27 of 53

Recursion

def factorial(x):

    value = 0

    if type(x) is not int or (x < 0):

        raise Exception('Illegal argument to factorial')‏

    elif x == 0:

        value = 1

    else:

        value = x * factorial(x – 1)‏

    return value

28 of 53

Function “Pointers”

def foo(x):

    return 2*x

print foo(2)‏

bar = foo

print bar(2)‏

 

def invoke(fn, arg):

    return fn(arg)

invoke(bar, 7)

29 of 53

Lambda Functions

# Construct simple functions “on the fly”

f = lambda x: 2*x

print f(2)‏

print f(4)‏

30 of 53

No “Switch” Statement in Python

def fun1(x):

    return 2*x

def fun2(x):

    return 3*x

fun_map = { 1 : fun1, 2 : fun2 }

z = 1

print fun_map[z](10)‏

z = 2

print fun_map[z](10)‏

31 of 53

Classes

  • Act as templates for objects
    • Implement both UDT's (User-Defined Types) and real objects with methods
  • Subclass the generic “object” class unless subclassing another class!
    • Otherwise, you get a "classic class", which is deprecated

32 of 53

Class Example

class MyClass(object):

    def __init__(self, x = 0.0, y = 0.0):

        self.x = x

        self.y = y

    def __str__(self):

        return '(' + str(self.x) + ',' + str(self.y) + ')'

instance = MyClass()‏

print instance # calls __str__

print MyClass(y = 3.2)‏

33 of 53

Class Methods

  • First parameter to EVERY method is ALWAYS in the instance of the class to be “worked on”
  • When calling class methods, this fact is usually obscured by the use of the dot (.) notation

34 of 53

Method Calls

class Adder(object):

    def add(self, a, b)‏:

        return a + b

inst = Adder() # Python is case-sensitive!

c = Adder.add(inst, 1, 2)‏

print c

c = inst.add(1, 2) # DON'T use “self” here – common mistake

print c

35 of 53

Inheritance

class A(object):

    def __init__(self, x):

        self.x = x

class B(A):

    def __init__(self, x, y):

        A.__init__(self, x) # Call superclass constructor

        self.y = y

a = A(10)‏

b = B(20, 30)‏

print a.x, b.x, b.y

36 of 53

Multiple Inheritance

class T(object):

    def __init__(self, x):

        self.x = x

class U(object):

    def __init__(self, y):

        self.y = y

class V(T, U):

    def __init__(self, x, y):

        T.__init__(self, x)‏

        U.__init__(self, y)‏

v = V(10, 20)‏

print v.x, v.y

37 of 53

Special Methods

class A(object):

    def __init__(self, x):

        self.x = x

    def __eq__(self, other):

        return self.x == other.x

    def __ne__(self, other):

        return self.x != other.x

a = A(1)‏

b = A(2)‏

print a == b

# Full list:

# http://docs.python.org/reference/datamodel.html#specialmethod-names

38 of 53

Deprecated Classic Classes

  • Often still seen in use (and lecture slides)‏
  • Classes that do not subclass object are called “classic”. Example: 

 

class Classic:�    # stuff

 

  • Deprecated since Python 2.2 – avoid using

39 of 53

Exceptions

  • Handle unforeseen events
    • Errors due to bugs
    • System problems (e.g. file not accessible)‏
    • Malfunctioning users
  • Similar to Java exceptions
  • try...except...else...finally blocks‏

40 of 53

Exception Handling

  • try:
    • Block of code that might cause an exception
  • except _____:
    • Code to catch a particular exception type
  • else:     # Only in Python >= 2.5
    • Code to run if no exception
  • finally:
    • Code to run whether or not exception occurred

41 of 53

Catching Exceptions

fh = None # Create file handle here so scope not limited to try: block

try:

    fh = open('nonexist-file', 'r')‏

except IOError, message:

    print message

else:

    print fh.read()

finally:

    if fh: # fh == None if file not successfully opened

        fh.close() # close() would throw uncaught exception without "if"

42 of 53

Raising Exceptions

x = 10

y = 0

if y == 0:

    raise Exception('Would divide by zero!')‏

else:

    print x / y

43 of 53

Custom Exceptions

class MyException(Exception):

    pass

class MyExceptionWithData(Exception):

    def __init__(self, message, data):

        Exception.__init__(self, message)‏

        self.data = data

raise MyExceptionWithData('Hello, World', 42)‏

44 of 53

Modules and Packages

  • Module == any Python file, located in the current directory, on the PYTHONPATH, or in system directories
  • Modules can be imported into the current module; individual objects (classes, functions, etc.) can also be imported into the current namespace
  • Packages: collections of modules

45 of 53

import Statement

import sys # import whole sys module

print sys.argv # refer to “stuff” in sys by using the dot notation

from sys import argv # import sys.argv into the current namespace

print argv # no longer need to use module name

from os import * # import everything in os module into the current

# namespace – considered bad practice (ns pollution)‏

46 of 53

Namespaces

  • Each module is its own namespace
    • Duplicate variable, function, class, etc. names OK as long as the names are in different namespaces
  • Namespace has the same name as the module when a module is imported
  • When a module is executed directly (as a script), the namespace has the special string value '__main__'
  • Test the current namespace with the __name__ built-in variable

47 of 53

Namespace Example

class Test(object):

   def __init__(self):

      print 'The constructor was called'

 

if __name__ == '__main__':

   t = Test()

   # Block only runs if this module was run

   # directly on the command line

48 of 53

Standard Modules

  • Implement Python's standard library
    • Standard C library plus much more
  • Common modules:
    • sys
    • os
    • os.path
  • Also have real and complex math libs from C
    • math and cmath modules

49 of 53

os module

import os

print os.getcwd()

print os.getenv('HOME')

pid = os.fork()

if pid == 0:

    print 'child'

else:

    print 'parent'

50 of 53

os.path module

import os.path

inittab = os.path.join('/etc', 'inittab')

somefile = os.path.join('c:', 'Windows', 'System32', 'file.txt')

print os.path.isfile(inittab)

print os.path.isfile(somefile)

print os.path.isdir('/etc')

51 of 53

sys module

import sys

if len(sys.argv) != 2:

    print >> sys.stderr, 'Usage:', sys.argv[0], '<filename>'

    sys.exit(2)

fh = open(sys.argv[1], 'r')

lines = fh.readlines()

for line in lines:

    print line.strip() + '!'

fh.close()

52 of 53

Module Documentation

  • See the “Global Module Index” for your version of Python
  •  http://docs.python.org/modindex.html

53 of 53

Example Python Applications

  • Stoker
  • Simple LISP Dialect for Teaching
    • http://code.google.com/p/sldt