BRIEF INTRODUCTION TO PYTHON 10/29/08 Talk given by: Don Miner (don1) http://maple.cs.umbc.edu/~don This document is available at http://maple.cs.umbc.edu/~don/projects/PythonNotes.txt Talk originally given for UMBC CMSC 331, Fall 2008, Dr. Tim Finin Get python and read more about it at: http://python.org/ print "Hello, World!" What is python? scripted language dynamically typed open source programming language available for all major operating systems "batteries included" - large standard library emphasizes productivity and code readability Can switch between styles (functional, OO, procedural) Benefits of Python Fast development cycle Platform independent Readable syntax Relatively fast (a lot of underlying modules are written in C/C++) Huge standard library (http://xkcd.com/353/) Powerful built-in types GUI layers (wxPython, Tkinter, pyGTK) Easy to integrate with other languages (Jython, SWIG, C/C++ modules) Can be used for cgi scripts Strong text processing capabilities (string class, regex module, glob module) Whitespace for indentation Easy to learn Easy to use exceptions Python interactive shell Built-in documentation: help(x), dir(x) Disadvantages of Python: Slow in comparison to compiled languages (usually not noticable) Doesn't catch type-conflict errors before run-time. E.g., x = 134.3, len(x) Whitespace for block delineation (if you use tabs and someone else uses spaces, can cause problems) No ++ / -- (this is to prevent ambiguity in some cases) Using the shell On linux.gl, just type "python" wireless-223-190:~ don$ python Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 3 + 4 7 >>> Entering an expression will result in the return value to be printed help and dir can be used to access the built-in docs >>> dir([]) ['__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'] Miscellaneous: You don't need ";" at the end of your lines (but every expression must be on a separate line) Comments are all one-line comments that start after a # >>> print "hello world" #comment hello world Instead of using { }, use a colon and a tab instead For example, In python if x > y: print "yes" in C++ if(x > y) { cout << "yes"; } Expressions in your script start at the 0th indent level (no indent) and move inwards as you use control structures. To run python scripts on the command line, either: $ python myscript.py $ ./myscript.py To execute myscript.py like you would any other command, you must add the following "shebang" #! line at the top of your script and set your script to executable "chmod u+x myscript.py". #!/usr/bin/env python Commonly used Data Types: int (automatically overflows to a "long" object) >>> 3 + 5 8 long - arbitrarily large int >>> 100**100 1000[...]00000000000000000L float >>> 3.0 + 4 7.0 >>> 1.0/3.0 0.33333333333333331 string >>> 'hello ' + 'world' 'hello world' >>> 'hello'[2] 'l' list - list of arbitrary objects >>> [9, 3, 1, 4.3, ["sublist"], [[],[]]] [9, 3, 1, 4.2999999999999998, ['sublist'], [[], []]] >>> [0,1,2,3,4][2] 2 tuple - same as list but "immutable" dictionaries - hash tables Input / Output: print Converts whatever it is given to a string then sends it to stdout Most objects in python can be converted to a string, natively Can separate statements by commas (print will put spaces between them) >>> print 1, 2, "hello", [1,2,3] 1 2 hello [1, 2, 3] Puts a newline at the end of statements, unless a comma is added at the end >>> print 'x', ; print 'y' x y raw_input(prompt) Takes input from the user from stdin after giving a prompt >>> inp = raw_input("what is your name? ") what is your name? don >>> print inp don open(file_path, mode) (mode = 'r' for read or 'w' for write; if omitted assumes 'r') To open a file for read: >>> file_h = open("life.cpp") You can read the entire contents of a file as one huge string >>> contents = file_h.read() Or, you can open the entire contents of a file as a list of lines: >>> contents = open("life.cpp").readlines() Files automatically close when they go out of scope -- but you can explicitly do this with .close() >>> file_h = open("life.cpp") >>> file_h.close() To open a file for writing: >>> file_h = open("outtest.txt", 'w') >>> file_h.write("hello world!\n") >>> file_h.close() Variables: Initializing a variable just means setting it to something >>> x = "hello" You can't use a variable until you initialize it: >>> x = y + 1 Traceback (most recent call last): File "", line 1, in NameError: name 'y' is not defined You can override a variable at any time by any type: >>> x = 3 You can "unpack" lists and tuples: >>> z = [x, x + 1] >>> a, b = z Lists are easy to create: >>> p = [x, z, a, b] >>> print p [3, [3, 4], 3, 4] More on these below... Control Structures: if-statements: >>> if 3 > 4: ... print "A" ... elif 3 == 4: ... print "B" ... elif 3 == "hello": ... print "C" ... else: ... print "D" ... D >>> if 4 > 3 and 9 > 6 or False: ... print "True!" ... True! boolean expressions: >>> True True >>> 4 > 9 False >>> 10 >= 9 True >>> not 3 > 4 True >>> 3 != 4 True for-loops: Different from C-style loops: all for loops are "for each" >>> for num in [9, 4, 3, 1, 9, 3]: ... print num, ... 9 4 3 1 9 3 range(n) creates a list of numbers (good for indexing) >>> x = ["hello", "world", "!!!"] >>> for i in range(len(x)): ... print x[i], ... hello world !!!! >>> x = [1,2,3,4] >>> for i in range(len(x)): ... x[i] += 1 ... >>> print x [2, 3, 4, 5] Note that the iterator object is a copy and won't affect the original list >>> x = [1,2,3,4] >>> for num in x: ... num += 1 ... >>> print x [1, 2, 3, 4] while-loop >>> i = 0 >>> while i < 10: ... i += 2 ... print i, ... 2 4 6 8 10 break & continue break stops the loop at that point >>> while True: ... i+= 1 ... if i == 10: ... break ... print i, ... 1 2 3 4 5 6 7 8 9 continue stops this current iteration and goes to the next one >>> for c in "HELLO WORLD": ... if not c in ["L", "O"]: ... continue ... print c, ... L L O O L Functions: Functions work in python much like they do any other language Functions are defined with the "def" keyword >>> def hello(name): ... return "hello " + str(name) ... >>> print hello("don") hello don Functions are objects and can be used as such! >>> def call_fun(fun_name, p): ... return fun_name(p) ... >>> call_fun(hello, "don") 'hello don' >>> print call_fun(hello, "don") hello don >>> def f1(n1, n2): ... return n1 * n2 ... >>> def f2(n1, n2): ... n3 = n1 + n2**2 + 4 ... return n3 ... >>> def f3(n1, n2): ... return f1(n1, n2) + f2(n2, n1) ... >>> fs = [f1, f2, f3] >>> for f in fs: ... print f(3, 4), ... 12 23 29 Of course, we can use recursion: >>> def fact(n): ... if n == 0: ... return 1 ... else: ... return n * fact(n - 1) ... >>> fact(5) 120 You can put built-in documentation into your functions, called docstrings. When someone calls help() on your function, it will show the docstring in the triple-quotes. >>> def foo(hello): ... """says hello to the person you pass""" ... print "hello", hello ... >>> foo('don') hello don >>> help(foo) Help on function foo in module __main__: foo(hello) says hello to the person you pass (END) Classes: Classes are more basic (in a good way, IMO) than what you will be use to from java You start out with the class definition All member functions pass a "this" pointer through the function parameters __init__ is called when the object is created >>> class Person: ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def birthday(self): ... self.age += 1 ... return self.age ... >>> don = Person("don", 23) >>> don.birthday() 24 >>> print don.name, "is", don.age, "years old" don is 24 years old Python handles inheritence >>> class Student(Person): Importing Modules You can import from the standard library with the statement "import" >>> import os >>> os.mkdir("test") >>> os.listdir(".") ['.DS_Store', 'test', 'somedir'] You can also import directly into your namespace (but may clobber some stuff) Try to avoid doing this >>> from os import * >>> getpid() 2777 Or, you can selectively import particular parts of a module >>> from os import popen >>> print popen("ls").read() #note, popen returns a file handle ['.DS_Store', 'test', 'somedir'] To import your own module, simply call "import mymodulename" (without .py) This will bring all the functions into the mymodulename. namespace Be careful, though, because all 0th level indentation expressions will be executed Exceptions: All errors in python are handled by exceptions When you get an unhandled exception, it crashed your program and gives you a message For example, divide by zero: >>> 4/0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: integer division or modulo by zero Or, type mismatch: >>> x + "hello" Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'str' We can handle these things with try/except (else statement gets executed if no exception is raised) >>> try: ... 4/0 ... except ZeroDivisionError, err: ... print "oh no", err ... else: ... print "woo" ... oh no integer division or modulo by zero We can raise our own exceptions with "raise" by passing an object >>> raise "hello" Traceback (most recent call last): File "", line 1, in hello There are plenty of built-in exceptions, such as NameError, TypeError, DivideByZero, etc. that you can pass around. When you make your own exception you should inherit from the Exception class >>> class MyError(Exception): ... def __init__(self, value): ... self.value = value ... def __str__(self): ... return repr(self.value) Numbers: int, float, long, complex You have the traditional stuff you are use to: +, -, *, /, % ** is exponent, and works for all types of numbers >>> 9.0 ** .5 # the square root of 9 3.0 >>> 4**5 # 4 to the 5th power 1024 >>> 9.0 ** -1 # the inverse of 9 0.1111111111111111 You can assign into the variable by putting a "=" after the operator >>> x = 9 >>> x %= 4 >>> print x 1 >>> x += 1 >>> print x 2 >>> x **= 2 >>> print x 4 Lists You can index into lists with the typical [] syntax: >>> x = [12, 30, 20, 102, 314, 1] >>> x[0] 12 To get the length of a list, use len(l) >>> len(x) 6 You can also index from the back of the list (-1 is the last position) >>> x[-2] 314 You may also "slice" the list by using 2 indices separated by a ":" Note that the result is RETURNED as a list, it does not change the original list If you leave one of the spots blank, it will make the assumption that you are talking about either the beginning or end of the list >>> x[1:4] [30, 20, 102] >>> x[1:-2] [30, 20, 102] >>> x[1:] # takes off the first element [30, 20, 102, 314, 1] >>> x[:-1] # takes off the last element [12, 30, 20, 102, 314] Also, you can set the step in which to select items by adding an additional ":" >>> x[::2] [12, 20, 314] >>> x[1::2] [30, 102, 1] You can also use a negative step, which makes it go backwards >>> x[::-1] [1, 314, 102, 20, 30, 12] You can append to lists in two ways: >>> x += [0] >>> x.append(99) >>> print x [12, 30, 20, 102, 314, 1, 0, 99] The list "variable" is a POINTER to the variable, so be careful! >>> y = x >>> y[0]= 52485 >>> print x [52485, 30, 20, 102, 314, 1, 0, 99] To make quickly make a semi-deep copy (only deep in the first layer) just use [:] >>> y = x[:] >>> y[0] = -9999 >>> print x [52485, 30, 20, 102, 314, 1, 0, 99] List also has a IN-PLACE (actually changes the object) sort method You can also pass a comparison function into sort >>> x.sort() >>> print x [0, 1, 20, 30, 99, 102, 314, 52485] Plenty of other methods (check out help([])) Tuples Tuples are lists with ( ) instead of [ ] They are the same except that they are immutable (cant be changed) Benefits: Guaranteed that it wont be changed by something it is passed to Detriments: Modifying them can be somewhat of a pain Can convert a list to a tuple by casting it (just like anything else) with tuple() >>> tuple([1,2,3,4,5]) (1, 2, 3, 4, 5) >>> (3,4,"hello") (3, 4, 'hello') Strings Strings in python are awesome - have lots of text processing power Strings are denoted by " or ' (there is no distinction, like in C) You can also create multi-lined strings with triple-quotes """ ... """ >>> s = """hello ... did you see that newline? ... another""" >>> print s hello did you see that newline? another Can use all the indexing tricks with strings that you can use in lists Immutable, like tuples You can convert most objects to strings by casting >>> x = "hello" + str(1) >>> print x hello1 Also, you can convert objects to strings by using backtics; however this is considered bad style by many >>> x = "hello" + `1` >>> print x hello1 You can strip whitespace from both sides with strip(), which is good for getting rid of unnecessary characters while reading/parsing input >>> " \n \n \n hello world ".strip() 'hello world' split will take the string and convert it into a list of strings, "splitting" on whitespace (or whatever you tell it to split on) This is really useful for reading in data files or parsing words >>> "13.2 1924.3 14 1021.4 entry".split() ['13.2', '1924.3', '14', '1021.4', 'entry'] You can do find/replace with replace >>> "hello world".replace("l", "X") 'heXXo worXd' Plenty of other methods (check out help("")) Dictionaries Dictionaries are hash tables, and are pretty easy to use To initialize one, use the following syntax (key/value pairs separated by : and ,) >>> x = { "name" : "don" , "age" : 23, 42 : "the answer"} To get the values, index by the key value >>> x["name"] 'don' >>> x[42] 'the answer' To add a new key/value pair, just assign into an index >>> x["dept"] = "csee" The keys member function returns the keys (for a for-loop maybe?) (note they are not returned in any order) >>> x.keys() ['dept', 'age', 42, 'name'] To check if a dictionary has a key, use has_key (or you can try to index it and catch the exception) >>> x.has_key('foo') False Plenty of other methods (check out help({})) Useful modules sys -- contains useful system stuff, like: handles to stdin, stdout -- act like files opened with "open" argv -- command line arguments exit -- exits out of a program os -- has all the fun stuff pertaining to interacting with the OS WARNING: os is NOT operating system independent fork, popen, chmod, pipe random -- all the random stuff random -- generates a random number between 0 and 1 shuffle -- moves around a list randomly math -- math stuff cos, sin, tan, acos, asin, atan, e, pi, floor, ceil, log, log10... datetime -- gets information about system time and allows for math on system times threads -- threading library for creating multi-threaded apps socket -- networking stuff re -- regular expressions so many more... plus you can install 3rd party modules List comprehensions You can do 1-liner for loops in python by using list comprehensions The return value in the left side of the expression is returned as an item in a list >>> [x ** 2 for x in range(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] Lambda You can definite in-line functions similar to LISP >>> (lambda x: x**2)(3) 9 You can use lambda to make dynamic functions >>> def make_incrementor (n): return lambda x: x + n >>> f = make_incrementor(2) >>> print f(42), f(f(42)) 44 46 Filter and map are powerful tools that are often used in conjunction with lambda >>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27] >>> print filter(lambda x: x % 3 == 0, foo) [18, 9, 24, 12, 27] >>> print map(lambda x: x * 2 + 10, foo) [14, 46, 28, 54, 44, 58, 26, 34, 64] Sample small programs: ## this program [inefficiently] finds the 10000th prime def isprime(n): for i in range(2, int(n**.5 + 1)): if n % i == 0: return False return True num_primes = 0 n = 2 cur_prime = 0 while num_primes <= 10000: if isprime(n): print n, "is prime" num_primes += 1 cur_prime = n n += 1 print "the 10,000th prime is", cur_prime ## crazy one liner that takes in data then sorts it by numerical value, then prints it back out ## it uses list comprehensions, an advanced for-loop print "\n".join([" ".join([str(i) for i in l]) for l in sorted([[ float(token) for token in \ line.strip().split() ] for line in sys.stdin.readlines()])]) ## this program shows how to use fork() to spawn off a child process import os pid = os.fork() if pid != 0: # if pid is not 0, it is the parent raw_input("gimi some suga") os.wait() # wait for the child to exit print "exiting"