## Python in 50 minutes

For more details, see the Python tutorial.

### A simple program

 # welcome.py print "Welcome to Sage Days!" 

 $python welcome.py Welcome to Sage Days!  Python code is compiled into byte code, which is executed in a Python virtual machine. But you may never know it unless you look. ### A computation  # computation.py a = 1 + 2 ** 3 print a   $ python computation.py 9 

Arithmetic operators:

 + addition - subtraction * multiplication / division ** exponentiation % modulus

Everything in Python is an "object" and has a type (e.g. int, float, string, etc). However, an object's type is a property of the object alone and not of a variable that points to it. This is called dynamic typing. It's a real convenience but occassionally requires a bit of thought.

 # computation.py a = 1 + 2 ** 3 print a a = "Now a is a string" print a 

 $python computation.py 9 Now a is a string  Anything in a line following the character "#" is ignored by Python. ### Data Types  integers long integers floats (like doubles in C or Java) strings lists dictionaries files ### The Python interpreter  >>> a = 5 >>> b = 3 >>> a*b 15 >>> a%b 2 >>> a/b 1  Suppose we really want 5/3 = 1.666...  >>> a * 1.0 /b 1.6666666666666667  or  >>> float(a)/b 1.6666666666666667  There are operators that convert between types if you need them. A useful one is str(a), which produces the string representation of the object a.  >>> a = 5 >>> a = 5.01 >>> a 5.0099999999999998 >>> str(a) '5.01'  Python will sometimes convert between types for us. For instance,  >>> 10**100 10000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000L  produces a long integer. But sometimes Python needs some help.  >>> a = 4 >>> "the value of a is " + a Traceback (most recent call last): File "", line 1, in ? TypeError: cannot concatenate 'str' and 'int' objects >>> "the value of a is " + str(a) 'the value of a is 4'  ### Strings Strings may be defined with either ' ' or " ".  >>> a = "hello" >>> print a hello >>> a = '$\alpha$' >>> print a$lpha$>>> a = r'$\alpha$' >>> print a$\alpha$ There are lots of operators for dealing with strings. How do we find them?  >>> dir(a) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] >>> help(a.replace) Help on built-in function replace: replace(...) S.replace (old, new[, count]) -> string Return a copy of string S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. >>> b = a.replace('alph', 'bet') >>> print b$\beta$ Strings are just arrays of characters. This will be useful when dealing with lists too.  >>> a = r'$\alpha$' >>> a[2:5] 'alp' >>> a[:4] '$\\al' >>> a[2:] 'alpha$' >>> a[-1] '$' >>> a[::2] '$apa'  Strings are immutable; that is, they may not be modified.  >>> a[2] = 'b' Traceback (most recent call last): File "", line 1, in ? TypeError: object does not support item assignment  ### Lists Lists are arrays, like strings, but they can hold arbitrary data types and they may be modified  >>> a = [10, 'sage', 3.14159] >>> a [10, 'sage', 3.1415899999999999]  or  >>> a = [ ] >>> a.append(10) >>> a.append("sage") >>> a.append(3.14159) >>> a [10, 'sage', 3.1415899999999999]  or  >>> a = [0]*10 >>> a [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   >>> dir(list) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']  Unlike strings, lists are mutable:  >>> a = [10, 'sage', 3.14159] >>> a[0] = 11 >>> a [11, 'sage', 3.1415899999999999]  Watch this:  >>> b = a >>> b.pop() 3.1415899999999999 >>> a [10, 'sage']  Variables are references to objects. When we say b = a, we simply create a new reference to the same object that a references. When we modify that object through the reference b, the changes appear under other references as well. If this is not the behavior we want, we need to make a copy of the object.  >>> a = [10, 'sage', 3.14159] >>> b = a[:] >>> b.pop() 3.1415899999999999 >>> a [10, 'sage', 3.1415899999999999]  ### Dictionaries Dictionaries provide a means of storing objects by key rather than relative position.  >>> a = { 'zero': [0, 0], 'e1': [1, 0], 'e2': [0, 1] } >>> a {'zero': [0, 0], 'e1': [1, 0], 'e2': [0, 1]} >>> a['zero'] [0, 0]  or  >>> a = { } >>> a['zero'] = [0, 0] >>> a['e1'] = [1, 0] >>> a['e2'] = [0, 1] >>> a {'zero': [0, 0], 'e1': [1, 0], 'e2': [0, 1]} >>> dir(a) ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', >>> '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', >>> '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', >>> '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', >>> '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', >>> 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', >>> 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', >>> 'update', 'values'] >>> a.has_key('zero') True >>> a.has_key('e3') False  Valid keys are objects that are hashable. (Unfortunately, lists are not hashable.) ### Conditionals  >>> a = -2 >>> if a < 0: ... print 'a < 0' ... elif a > 0: ... print 'a > 0' ... else: ... print 'a = 0' ... a < 0  Notice the syntax. Blocks of code are denoted by identation rather than { ... }. A colon ends a statement before a block of code. Also, we do not need parentheses around the logical expression.  >>> a = [3, 5, 7, 11, 13] >>> if 2 not in a and len(a) < 10: ... a.insert(0, 2) ... >>> a [2, 3, 5, 7, 11, 13]  The values of booleans are True or False. ### Loops  >>> for x in a: ... print x ... 2 3 5 7 11 13   >>> a = 3.2 >>> while a > 1: ... a /= 2 ... >>> str(a) '0.8'  break causes us to leave a loop immediately.  >>> a = [3, 5, 7, 11, 13] >>> for x in a: ... if x == 7: ... print 'list contains 7' ... break ... list contains 7  In the same way, continue causes us to go back to the top of the loop immediately.  >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> for i in range(10): ... print i*i ... 0 1 4 9 16 25 36 49 64 81   >>> for i in range(-5, 6, 2): ... print i ... -5 -3 -1 1 3 5  range generates the list before running the loop.  xrange is similar to range except that elements in the list are generated as needed.  >>> sum = 0 >>> for x in xrange(1, 1000001): ... sum += x ... >>> sum 500000500000  List comprehensions give a convenient way to create lists  >>> squares = [ x*x for x in range(0, 11) ] >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]  ### Working with files  >>> output = open('out', 'w') >>> output.write('hello\n') >>> output.write('there\n') >>> output.close() >>> >>> input = open('out') >>> lines = input.readlines() >>> lines[0] 'hello\n' >>> lines[1] 'there\n' >>> input.close()  ### Functions We just added together the first million positive integers. We can turn this into a function so that we may vary the number of terms to add.  >>> def sum(n): ... s = 0 ... for x in xrange(1, n+1): ... s += x ... return s ... >>> sum(1000000) 500000500000 >>> sum(35) 630  Notice that we do not need to specify the type of the object returned by the function. Suppose we want to allow our function to add the integers between a and n.  # sum.py # Allow sum(n) to add [1, 2, 3, ... n] # or sum(a, n) to add [a, a+1, ..., n] def sum(*args): if len(args) == 1: start = 1 stop = args[0] else: start = args[0] stop = args[1] s = 0 for x in xrange(start, stop+1): s += x return s print sum(1000000) print sum(3, 4)   $ python sum.py 500000500000 7 

Functions may have no arguments. In this case, you must put () after the function's name when calling it.

 >>> def f(): ... print 'hi' ... >>> f >>> f() hi >>> 

### Scope of variables

Variables inside a block of code are only visible inside that block.

 # scope0.py def f(n): x = 3 return x**n print f(4) print x 

 $python scope0.py 81 Traceback (most recent call last): File "scope0.py", line 6, in ? print x NameError: name 'x' is not defined   # scope1.py x = 3 def f(n): return x**n print f(4) print x   $ python scope1.py 81 3 

 # scope2.py x = 3 def f(n): x += 1 return x**n print f(4) print x 

 $python scope2.py Traceback (most recent call last): File "scope2.py", line 6, in ? print f(4) File "scope2.py", line 3, in f x += 1 UnboundLocalError: local variable 'x' referenced before assignment   # scope3.py x = 3 def f(n): global x x += 1 return x**n print f(4) print x   $ python scope3.py 256 4 

### Classes

Python is an object-oriented language so we may create our own data types, which will hold data and allow us to access and manipulate the data. This is a good way to get to know your  self.

 # Circle.py import math class Circle: def __init__(self, center, radius): self.center = center self.radius = radius def area(self): return math.pi * self.radius**2 def contains(self, point): dx = point[0] - self.center[0] dy = point[1] - self.center[1] return math.sqrt(dx*dx + dy*dy) < self.radius 

 >>> c = Circle([3,4], 5) >>> c.area() 78.539816339744831 >>> c.contains([1,1]) True >>> c.contains([-1,1]) False >>> c.center [3, 4] >>> c.center = [2,3] # don't do this! 

In general, it is better to access variables inside a class using functions provided by the class.

 # Circle.py import math class Circle: def __init__(self, center, radius): self.center = center self.radius = radius def area(self): return math.pi * self.radius**2 def contains(self, point): dx = point[0] - self.center[0] dy = point[1] - self.center[1] return math.sqrt(dx*dx + dy*dy) < self.radius def getradius(self): return self.radius def getcenter(self): return self.center def setradius(self, r): self.radius = r def setcenter(self, c): self.center = c 

### Modules

 # Geometry.py import math class Circle: def __init__(self, center, radius): self.center = center self.radius = radius def area(self): return math.pi * self.radius**2 def contains(self, point): dx = point[0] - self.center[0] dy = point[1] - self.center[1] return math.sqrt(dx*dx + dy*dy) < self.radius class Square: def __init__(self, ll, side): self.lowerleft = ll self.side = side def area(self): return self.side * self.side def contains(self, point): dx = point[0] - self.lowerleft[0] dy = point[1] - self.lowerleft[1] if dx < 0 or dx > side: return False if dy < 0 or dy > side: return False def unitcircle(): return Circle([0, 0], 1) def unitsquare(): return Square([0, 0], 1) 

Using the module

 # geometrytest.py import Geometry square = Geometry.unitsquare() circle = Geometry.unitcircle() print square.area(), circle.area() 

 $python geometrytest.py 1 3.14159265359  or  # geometrytest.py from Geometry import * square = unitsquare() circle = unitcircle() print square.area(), circle.area()   $ python geometrytest.py 1 3.14159265359