Python
Like several other languages including ML and Ruby, you use Python in two ways:
Call this file hello.py
print 'Hello, world'
and run it like this
Note that Python has a print statement (not a print function), that automatically puts a newline at the end! Cool, huh? Another simple script:
"""This script prints some Pythagorean triples."""
for c in range(1, 100):
for b in range(1, c):
for a in range(1, b):
if a * a + b * b == c * c:
print '(', a, b, c, ')'
And another
"""This script writes the Fibonacci numbers up to and including
the first commandline argument.
"""
import sys
n = int(sys.argv[1])
a, b = 0, 1
while b <= n:
print b,
a, b = b, a+b
The prompt is ">>>". The continuation line is "...". For multiline inputs, finish with a blank line (hit Enter without entering anything first)
$ python
Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02)
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 5 * 3 + 6 / 1
21
>>> 5 / 2
2
>>> 5.0 / 2
2.5
>>> 'dog'
'dog'
>>> x = 4
>>> x
4
>>> {'x': 4, 'y': 6}
{'y': 6, 'x': 4}
>>> s = 'hello there'
>>> s.upper()
'HELLO THERE'
>>> s.split(' ')
['hello', 'there']
>>> 5 < 9
True
>>> x = [1, True, 7.5, 'Hello', {'name':'sparky', 'breed':'shepherd'}, []]
>>> x[2]
7.5
>>> x[4]
{'breed': 'shepherd', 'name': 'sparky'}
>>> x[4]['name']
'sparky'
>>> x,y,z = 10,20,30
>>> x,y = y,x
>>> if x == 20:
... print 'dog'
...
dog
>>> def triple(x):
... return x * 3
...
>>> triple(5)
15
>>> x + y + 2j
(30+2j)
>>> (5-1j)*1j
(1+5j)
>>> triple(1j)
3j
Absolutely everything in Python is an object. You get the id of an object with the id function, and the type of the object with the type function.
>>> id(8)
9786484
>>> id(202342353245553)
10527880
>>> id(False)
504954072
>>> id(2 < -4)
504954072
>>> id(None)
505028096
>>> id("hello")
10951328
>>> id(id)
10532224
>>> type(8)
<type 'int'>
>>> type(242354234235665657543)
<type 'long'>
>>> type(None)
<type 'NoneType'>
>>> type("woo")
<type 'str'>
>>> type(u"woohoo")
<type 'unicode'>
>>> type(False)
<type 'bool'>
>>> type(lambda x: x * x)
<type 'function'>
>>> type(id)
<type 'builtin_function_or_method'>
>>> type({'CA':'Sacramento','HI':'Honolulu','AK':'Juneau'})
<type 'dict'>
>>> type(type)
<type 'type'>
>>> type(type(3))
<type 'type'>
>>> int
<type 'int'>
>>> type(2.77e6)
<type 'float'>
>>> type(3-3j)
<type 'complex'>
A type's constructor has the same name as the type. Most constructors do the obvious thing when given arguments of different types.
>>> str(42)
'42'
>>> bool(35443)
True
>>> bool(0)
False
>>> int(False)
0
>>> int(True)
1
>>> float(92)
92.0
>>> int(89.3221)
89
>>> int(99.99999999)
99
>>> int(-99.9999)
-99
>>> float(False)
0.0
>>> complex(5)
(5+0j)
>>> complex(3.6, 99)
(3.6000000000000001+99j)
>>> long(32.4E39)
32399999999999999195056519073840702160896L
>>> unicode(25)
u'25'
>>> str(8.9E5)
'890000.0'
>>> int("32")
32
>>> list((3,7,5))
[3, 7, 5]
>>> tuple([1,2,-17,"dog"])
(1, 2, -17, 'dog')
>>> list("abc")
['a', 'b', 'c']
>>> list({"x": 5, "y": 7})
['y', 'x']
The three kinds of built-in containers are sequences, sets, and dictionaries
The built-in container types are
For all sequences s and t, sequence elements x, and integers i, j, k, and n, you can write
s[i] s[i:j] s[i:j:k] s[:i] s[i:]
len(s)
x in s
s + t s * n
s < t s <= t
s == t s != t s >= t s > t
iter(x)
Functions are introduced with def, and called with the usual f(x) notation.
"""This is a simple script that displays the mean and median
of an array of values, passed in on the command line.
"""
import sys;
import operator;
def median(a):
"""Return the median of sequence a."""
a = sorted(a)
length = len(a)
if length % 2 == 1:
return a[length/2]
else:
return (a[length/2] + a[length/2 - 1]) / 2.0
def sum(a):
"""Return the sum of the values in the sequence a. Python
already has a built-in sum function so you'd never actually
write one yourself, but this is one way to do it if you
wanted to.
"""
return reduce(operator.add, a, 0)
def mean(a):
"""Return the mean of the values in sequence a."""
return float(sum(a)) / len(a)
print "input array is", sys.argv
numbers = [int(x) for x in sys.argv[1:]];
print "list is:", numbers
print "sum is:", sum(numbers)
print "mean is:", mean(numbers)
print "median is:", median(numbers)
print "list is:", numbers, "(just making sure it was not changed)"
You can also have defaults for arguments, and call them with the parameter names:
>>> def f(x, y=5, z=10): ... return (x, y, z) ... >>> f(1) (1, 5, 10) >>> f(1,7) (1, 7, 10) >>> f(1,8,20) (1, 8, 20) >>> f(2,3,5,7) Traceback (most recent call last): File "", line 1, in ? TypeError: f() takes at most 3 arguments (4 given) >>> f(2,z=5) (2, 5, 5) >>> f(x=4,y=9) (4, 9, 10) >>> f(z=1,x=10,y=3) (10, 3, 1)
You can have calls with an unlimited number of arguments
>>> def g(x, *y): ... return "x is " + str(x) + " and y is " + str(y) ... >>> g(4) 'x is 4 and y is ()' >>> g(3, 4) 'x is 3 and y is (4,)' >>> g(8,3,4,5,6,2,3) 'x is 8 and y is (3, 4, 5, 6, 2, 3)'
"""Examples of higher order functions in Python.
This script contains both examples of defining your
own higher order functions, and how you use the builtins
map, reduce, and filter.
"""
def compose(f, g):
"""Returns the functional composition of f and g"""
return lambda x: f(g(x))
def twice(f):
"""Returns the function which applies f to its argument twice"""
return compose(f, f);
# Some plain old functions
def isOdd(x): return x % 2 == 1
def twoXPlusY(x, y): return 2 * x + y
def square(x): return x * x
def addSix(x): return x + 6
# The value of a variable can be a function
addSixThenSquare = compose(square, addSix)
addTwelve = twice(addSix)
# Illustration of the functions via unit tests
failures = 0
def assertEquals(x, y):
global failures
if x != y: failures += 1
assertEquals(addSixThenSquare(9), 225)
assertEquals(twice(square)(3), 81)
assertEquals(addTwelve(100), 112)
# map, filter, and reduce are builtins.
assertEquals(map(square, range(5)), [0, 1, 4, 9, 16])
assertEquals(filter(isOdd, range(7)), [1, 3, 5])
assertEquals(reduce(twoXPlusY, [3, 6, -4, 2, -7], 0), 77)
print failures, "failure(s)"
Also, The Linux Gazette has an article on Functional Programming in Python.
For more on closures in Python, see this explanation by Jacek Generowicz.
A list comprehension just a list written with an expression used to generate the list elements. They are often used in place of some functional programming constructs
>>> a = [1, 2, 10, 6]
>>> b = [3, 0, 4, -8]
>>> [4 * x for x in a]
[4, 8, 40, 24]
>>> [2 / x + 5 for x in a if x < 4]
[7, 6]
>>> [x + y for x in a for y in b]
[4, 1, 5, -7, 5, 2, 6, -6, 13, 10, 14, 2, 9, 6, 10, -2]
>>> [(x, x**3) for x in a]
[(1, 1), (2, 8), (10, 1000), (6, 216)]
>>> [x + y for x in a for y in b if y <= 0]
[1, -7, 2, -6, 10, 2, 6, -2]
>>> [a[i] * b[i] for i in range(len(a))]
[3, 0, 40, -48]
>>> [str(round(355/113.0, i)) for i in range(1,6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
>>> [(i, 2**i) for i in range(10)]
[(0, 1), (1, 2), (2, 4), (3, 8), (4, 16), (5, 32), (6, 64), (7, 128), (8, 256), (9, 512)]
>>> [x for x in [y*y for y in range(10)] if x % 2 == 0]
[0, 4, 16, 36, 64]
>>> names = ["ALICE", "BOb", "cAROl", "daVE"]
>>> [(n.lower(), n.upper()) for n in names]
[('alice', 'ALICE'), ('bob', 'BOB'), ('carol', 'CAROL'), ('dave', 'DAVE')]
>>> [i for i in range(10,30) if i not in range(5, 40, 2)]
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
>>> [(a,b,c) for c in range(1,30) for b in range(1,c) for a in range(1,b) if a*a+b*b==c*c]
[(3, 4, 5), (6, 8, 10), (5, 12, 13), (9, 12, 15), (8, 15, 17),
(12, 16, 20), (15, 20, 25), (7, 24, 25), (10, 24, 26), (20, 21, 29)]
Python list comprehensions are
Operators are really methods of a class that get a nice syntax via rewriting rules.
>>> x = 3; >>> x.__add__(4) 7
Modules are trivial in Python: no special syntax is required: the module name is just the file name. For example, put this code in roman.py
"""A module containing a single subroutine that returns the roman
numeral representation of an integer."""
def to_roman(n):
"""Returns a string representing the roman numeral for n"""
if (type(n) != int):
raise Exception(repr(n) + " is not an integer");
if (n <= 0):
raise Exception("%d has no Roman equivalent" % n);
map = [
(1000, 'M'),
(900, 'CM'),
(500, 'D'),
(400, 'CD'),
(100, 'C'),
(90, 'XC'),
(50, 'L'),
(40, 'XL'),
(10, 'X'),
(9, 'IX'),
(5, 'V'),
(4, 'IV'),
(1, 'I'),
]
roman_string = ""
for value, name in map:
while (value <= n):
roman_string += name
n -= value
return roman_string
if __name__ == "__main__":
n = input('Enter an integer: ')
print n, "is", to_roman(n)
print "And here are other interesting roman numerals"
for n in [3, 89, 22, 11]:
print n, "is", to_roman(n)
Here is a unit tester that uses it
"""A trivial unit test for the roman package."""
import roman
test_cases = {
3: 'III',
89: 'LXXXIX',
1002: 'MII',
11: 'XI',
444: 'CDXLIV',
}
# Tests roman.to_roman
for n in test_cases:
expected = test_cases[n];
actual = roman.to_roman(n);
if expected != actual:
raise Exception("Found %s but expected %s for %s " %
(actual, expected, n))
# If we didn't die, we made it.
print "All tests passed"
Here is an illustration of the try statement
"""A simple script that reads from integers from standard
input and writes their roman equivalents to standard output.
The input file is assumed to have one integer per line.
Blank lines are allowed and will be skipped.
"""
import roman, sys, string
for line in sys.stdin.readlines():
line = string.strip(line);
if line:
try:
print line, "is", roman.to_roman(int(line))
except Exception, e:
print e
import math
class Circle:
"A circle with a 2-D center point and a radius."
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
def area(self):
"Returns the area of the circle"
return math.pi * (self.radius ** 2)
def perimeter(self):
"Returns the circumference of the circle"
return math.pi * self.radius * 2
def expand(self, factor):
"Increases the radius by the given factor"
self.radius *= factor
return self
def move(self, dx, dy):
"Moves the center point by <dx, dy>"
self.x += dx
self.y += dy
return self
def __str__(self):
return "Circle at (%g,%g) with r=%g" % (self.x, self.y, self.radius)
Using
>>> from circle import * >>> c = Circle(4, 3, 10) >>> c.area() 314.15926535897933 >>> c.perimeter() 62.831853071795862 >>> c.move(3, 2) <circle.Circle instance at 0x00A77058> >>> print c Circle at (7,5) with r=10 >>> c.move(-3,2).expand(5) <circle.Circle instance at 0x00A77058> >>> print c Circle at (4,7) with r=50 >>> Circle.area.__doc__ 'Returns the area of the circle'
Nothing too unusual here, except that there's no built-in super keyword, so __init__ calls to a superclass must name the superclass
"""A module with talking animals."""
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print self.name, "says", self.sound()
class Cow(Animal):
def __init__(self, name):
Animal.__init__(self, name)
def sound(self):
return "moo"
class Horse(Animal):
def __init__(self, name):
Animal.__init__(self, name)
def sound(self):
return "neigh"
class Sheep(Animal):
def __init__(self, name):
Animal.__init__(self, name)
def sound(self):
return "baaaaa"
if __name__ == "__main__":
s = Horse("CJ")
s.speak()
c = Cow("Bessie")
c.speak()
Sheep("Little Lamb").speak()
An iterator is like an "on-demand sequence" — it saves space and can potentially be infinite. Compare
for line in file.readLines():
# ...
with
for line in file:
# ...
An iterator is any object with two methods:
Any object that has an __iter__() method that returns an iterator can be used in a for statement.
"""A couple of interesting iterators."""
class fibs:
"""Fibonacci iterator (infinite): 0, 1, 1, 2, 3, 5, 8, ..."""
def __init__(self):
self.a, self.b = 0, 1
def next(self):
current, self.a, self.b = self.a, self.b, self.a + self.b
return current
def __iter__(self):
return self
class collatz:
"""Collatz sequence iterator, supply start value at initialization"""
def __init__(self, start):
self.n = start
self.started = False
def next(self):
if not self.started:
self.started = True
return self.n
elif self.n == 1:
raise StopIteration
elif self.n % 2 == 0:
self.n = self.n / 2
else:
self.n = 3 * self.n + 1
return self.n
def __iter__(self):
return self
if __name__ == "__main__":
# Demonstrate fibonacci iterator
f = fibs()
for i in f:
print i,
if i > 1000000:
break;
print
print
# Demonstrate collatz iterator
c = collatz(47)
for i in c:
print i,
print
print
Generators are a way cool way to make iterators — they sort of generate the iterator for you.
"""A couple of interesting generators."""
def fib():
"Fibonacci generator (infinite): 0, 1, 1, 2, 3, 5, 8, ..."
a, b = 0, 1
while True:
current, a, b = a, b, a + b
yield current
def collatz(n):
"Collatz generator starting at n"
while True:
yield n
if n == 1:
return
elif n % 2 == 0:
n = n / 2
else:
n = 3 * n + 1
if __name__ == "__main__":
# Show off the fibonacci generator
for i in fib():
print i,
if i > 1000000:
break;
print
print
# Show off the collatz generator
for i in collatz(47):
print i,
print
print
and del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try
From the Python Reference Manual, Section 3.2:
| Type | Notes |
|---|---|
| NoneType | contains only one value: None |
| NotImplementedType | contains only one value: NotImplemented |
| EllipsisType (ellipsis) | contains only one value: Ellipsis |
| Number | all numbers are immutable |
| Integer | |
| IntType (int) | at least -2147483648..2147483647 |
| LongType (long) | range limited only by available memory |
| BooleanType (bool) | contains only two values: True, False |
| FloatType (float) | hardware's double-precision type |
| ComplexType (complex) | pair of hardware doubles (z.real, z.imag) |
| Sequence | finite, ordered, indexed from 0, len(), a[i], a[i:j] |
| Immutable Sequence | a sequence that cannot have its value changed |
| StringType (str) | contain bytes (convert to/from ints with chr() and ord()) |
| UnicodeType (unicode) | contain code units (convert to/from ints with unichr() and ord()) |
| TupleType (tuple) | written as (), (x,), (x,y), (x,y,z), etc. |
| Mutable Sequence | subscripted and slice forms can be lvalues; del statement okay |
| ListType (list) | written as [], [x], [x,y], [x,y,z], etc. |
| Mapping | something indexable with the a[k] syntax, k can be almost anything, not just an integer |
| DictionaryType (dict) | the only kind of mapping type |
| Callable | anything supporting the call syntax |
| User-defined Function | created by a function definition |
| User-defined Method | basically a function defined within a class |
| Generator Function | any function with a yield statement |
| Built-in Function | wrapper around a C function (e.g. len(), math.sin()) |
| Built-in Method | wrapper around a C function, w/ implicit __self__ argument |
| Classic Class | "calling" a class is sugar for construction and calling __init__() |
| Class Type | new-style classes, similar to classic classes but can use __new__() |
| Class Instance | any instance of a class with a __call__() method |
| Module | a collection of definitions and statements put into a file and imported into other code |
| Class | created by a class definition |
| Class Instance | an object created by invoking a constructor |
| File | an open file, created with open() and related operations. sys.stdin and sys.stdout are examples. |
| Internal | used internally, but exposed to the programmer |
| Code | bytecode. Immutable. |
| Frame | execution frames, occurring in traceback objects |
| Traceback | created when an exception is thrown, accessible within the tuple returned by sys.exc_info() |
| Slice | examples: a[i:j:step], a[i:j, k:n], a[..., i:j] |
| Static Method | created by built-in staticmethod() constructor |
| Class Method | created by built-in classmethod() constructor |
The symbol table in this module is always searched last, so it's like all these names are made available to all scripts and the interactive shell.
On ActiveState Python 2.4 for Windows, the module contains:
ArithmeticError AssertionError AttributeError DeprecationWarning EOFError Ellipsis EnvironmentError Exception False FloatingPointError FutureWarning IOError ImportError IndentationError IndexError KeyError KeyboardInterrupt LookupError MemoryError NameError None NotImplemented NotImplementedError OSError OverflowError OverflowWarning PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError True TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UserWarning ValueError Warning WindowsError ZeroDivisionError _ __debug__ __doc__ __import__ __name__ abs apply basestring bool buffer callable chr classmethod cmp coerce compile complex copyright credits delattr dict dir divmod enumerate eval execfile exit file filter float frozenset getattr globals hasattr hash help hex id input int intern isinstance issubclass iter len license list locals long map max min object oct open ord pow property quit range raw_input reduce reload repr reversed round set setattr slice sorted staticmethod str sum super tuple type unichr unicode vars xrange zip
There are a few hundred "standard" modules in the Python Library.