[an error occurred while processing this directive]
Python, a reference to Monty Python's Flying Circus, is an open-source scripting language that is extremely flexible and powerful. Python is a server-side language, meaning that python programs run on the web server in response to a user request to produce an output web page.
This document should provide enough information to get started writing Python programs, but you may need to consult the online Python documentation (available at http://www.python.org/doc/) to find out about primitive procedures in Python that may be useful for your projects.
Python is a universal programming language — this means every process we could describe using a Turing Machine (or using Scheme), we can also describe in Python. The syntax of Python is very different from Scheme, but most of the evaluation rules are similar.
All Python code is a sequence of statements separated by newlines:
PythonCode ::= StatementsNote that unlike in Scheme, the whitespace (such as new lines) has meaning in Python. Statements cannot be separated into multiple lines, and only one statement may appear on a single line. Indentation within a line also matters. Instead of using parentheses to provide code structure, Python uses the indentation to group statements into blocks.
Statements ::= Statement <newline> Statements
Instructions ::=
Python has many different kinds of statements. The three you will use most are assignment, applications and function definitions:
Statement ::= AssignmentStatement
Statement ::= ApplicationStatement
Statement ::= FunctionDefinition
AssignmentStatement ::= Variable = Expression
To evaluate an AssignmentStatement, Python evaluates the Expression and places the value in the place named Variable. (Just like the Scheme evaluation rule for set!). The only difference is if there is not already a place named Variable, Python will create a new place as a result of the assignment statement. Hence, the Python statement x = 1 will act like (define x 1) if there is no place already named x, and like (set! x 1) if there is already a place named x.
An expression in Python is similar to an expression in Scheme — it is a code fragment that evaluates to a value. In Python, expressions use infix notation. The operator is placed between the operands (except for function calls, described below). Python supports most of the standard arithmetic operators. Here are some examples:
Scheme | Python |
---|---|
(define four 4) (define two (/ four 2)) (define bigger (< (* four four) 17) (printf "four: ~a two: ~a bigger: ~a" four two bigger) four: 4 two: 2 bigger #t |
four = 4 two = four / 2 bigger = (four * four) < 17 print "four: %d two: %d bigger: %d" % (four, two, bigger) four: 4 two: 2 bigger: 1 |
The parentheses in the assignment to bigger are necessary for grouping oprations. Without them it would mean (* four (< four 17)) instead of (< (* four four) 17).
Python uses 1 to mean true. Python considers the empty string, 0, and the empty list to be false, and (almost) everything else true.
The print procedure takes a string as input followed by a % and a list of values (in parentheses). The values are matched to the % codes in the string. Different % codes are used for printing different types of values. Here, %d is used to print an integer.
ApplicationStatement ::= Name ( Arguments )So, Proc (Arguments) in Python is similar to (Proc Arguments) in Scheme (except there are no commas between the arguments in Scheme).
Arguments ::=
Arguments ::= MoreArguments
MoreArguments ::= Argument ,MoreArguments
MoreArguments ::= Argument
Argument ::= Expression
Python only has a few primitive functions, but a very extensive standard library.
FunctionDefinition ::= def Name ( Parameters ): <newline> StatementsFor example,
Parameters ::=
Parameters ::= MoreParameters
MoreParameters Parameter ,MoreParameters
MoreParameters ::= Parameter
Parameter ::= Variable
Scheme | Python |
---|---|
(define square (lambda (x) (* x x))) (define quadratic (lambda (a b c x) (+ (* a (square x)) (* b x) c))) (display (quadratic 2 3 7 4)) 51 |
def square (x): return x * x def quadratic (a, b, c, x): return a * square (x) + b * x + c print quadratic (2,3,7,4) 51 |
Note that unlike Scheme, where the procedure body is an expression and the value of an application is the value of that expression (evaluated in the new environment with the parameters bound), in Python, the procedure body is a list of Statements. The special statement,
ReturnStatement ::= return Expressionis used to return a value from a procedure. When execution encounters a return statement, the Expression is evaluated and returned to the caller.
Python also provides a form lambda for making procedures the way you would in Scheme using lambda:
Expression ::= lambda Parameters : ExpressionThe parameters are defined as above, and the body is the one expression (a return before the expression is implied). For example, (lambda (a b) (+ a b)) would be lambda a, b: a + b. Here's an example:
def makeAdder (a): return lambda b: a + b add5 = makeAdder (5) print "Adding: " + str(add5(2))
Adding: 4
Note that here we concatenate the string "Adding: " with str(adder(2,2)); str converts the output of adder(2,2) to a string.Python does not evaluate applications the same way as Scheme, however. In particular, Python does not create a chain of frames for evaluation purposes. Instead, there are only two namespaces (Pythonspeak for frames): the global namespace and the local namespace.
Statement ::= if (Expression): <newline> Statementsis equivalent to (if Expression (begin Statements)).
Python also supports alternative clauses but uses else to distinguish them:
Statement ::= if (Expression) :is equivalent to (if Expression (begin Statements1) (begin Statements2)).
Statements1
else :
Statements2
Statement ::= while (Expression):The indentation of the statements determines the statements that are looped.
Statements
Here is an example that will print out the first 10 Fibonacci numbers:
i = 1; a = 1; b = 1; while (i <= 10): print "Fibonacci %s = %s" % (i,b); next = a + b; a = b; b = next; i = i + 1; print "Done."
Scheme | Python |
---|---|
(define four 4) (define pi 3.14159) (define half 1/2) |
four = 4 pi = 3.14159 nothalf = 1/2 (evaluates to 0) half = 1.0/2.0 (evaluates to .5) |
What happened when we defined nothalf?
Unlike Scheme, Python makes a distinction between integer math and floating point math. This normally isn't that important; when we do math between the same types, the result is the same type, and when we do math with a floating point number and an integer, the type returned is a floating point number. However, the result of division of an integer by another integer is not necessarily an integer -- Python will silently discard the fractional part of the answer. By writing the operands with decimal points, we ensure that the operation will return a floating point number. This problem only rarely occurs, but you should always be aware of it when searching for bugs.
You can concatenate (run together) two strings by using the plus sign (+):
name = "Spot"If you want a literal quote to appear in a string you print, use \":
print "See " + name + " run."
print "My name is \"Spot\"."The triple quote, """ is an easy way to print large chunks of text that can include double quotes and new lines. For example,
print """ "I find that the harder I work, the more luck I seem to have." --- Thomas Jefferson """will print out
"I find that the harder I work, the more luck I seem to have."
--- Thomas Jefferson
The biggest difference between a Scheme list and a Python list is that elements in Python lists are can be accessed directly. This means that we can access any element of the list if we know it's number; we had to write our own function in Scheme to get this functionality.
Scheme | Python |
---|---|
> (define lst (list 10 20 30)) > (car lst) 10 > (car (cdr (cdr lst))) 30 |
lst = [10, 20, 30] print lst[0] 10 print lst[2]20 |
Indices in Python are much more powerful than that, however. We can "slice" lists to only look at a subset of the list data.
(Note that decimal numbers are not exact in Python! We put 302.234 in the list, but the printed value is 302.23399999999998.)lst = [10, 20, 40, "string", 302.234]
print lst[0:2]
[10, 20]
print lst[:3]
[10, 20, 40]
print lst[3:]
['string', 302.23399999999998]
Finally, if we want to iterate over an entire list, we use the for statement:
Statement ::= for VaribleList in ExpressionList : StatementsFor example,
def sum (lst): total = 0 for el in lst: total = total + el return total print sum([1, 2, 3, 4])
10
A dictionary is a list of (key, value) pairs. In Python, the key can be any "immutable" object (tuples, strings, numbers), and the value can be any Python object. We can initialize a dictionary using the initialization expression:
DictionaryInitializationStatment ::= Variable = { InitializationExpressions }
InitializationExpressions ::=
InitializationExpressions ::= InitializationExpression, InitializationExpressions
InitializationExpression ::= Expression : Expression
The expression before the : is the key, and the following expression is the associated value.
We can set the value associated with a key using a set statement:
SetStatement ::= Expression [ Expression ] = ExpressionWe get the value associated with a key using:
FetchExpression ::= Expression [ Expression ]The first expression in a fetch expression must evaluate to a dictionary.
Here are some examples:
yellow = { 'red': 255, 'green': 255, 'blue': 0 } print '(%s, %s, %s)' % (yellow['red'], yellow['green'], yellow['blue'])(255, 255, 0)
yellow['red'] = 230 print '(%s, %s, %s)' % (yellow['red'], yellow['green'], yellow['blue'])(230, 255, 0)
Of course, we can put arrays in arrays, just like we can make lists of lists in Scheme. To do something to everything in the array, we first have to use the built-in "keys" method of the dictionary. For example, to reset yellow, we would do:
for key in yellow.keys():
yellow[key] = 0
ClassDefinition ::= class Name:
FunctionDefinitions
These function definitions will form the "methods" of the class. There are lots of special methods, and we can also create our own. The only special method we'll worry about now is the __init__ method that is used when we create an instance of an object. The __init__ method is similar to the make-class methods from Problem Set 6.
Here's an example:
Scheme | Python |
---|---|
(define (make-object name) (lambda (message) (case message ((class) (lambda (self) 'object)) ((object?) (lambda (self) #t)) ((name) (lambda (self) name)) ((say) (lambda (self list-of-stuff) (if (not (null? list-of-stuff)) (display-message list-of-stuff)) 'nuf-said)) ((install) (lambda (self . args) 'installed)) (else no-method)))) |
class my_object: def __init__(self, name): self._name = name def is_object(self): return True def whatclass(self): return type(self) def name(self): return self._name def say(self, lst): for x in lst: print x def install(self, args): print "Installed" |
Although the differences between the two languages prevent a direct translation (for example, object and class are both "reserved" words in Python", and we can't have both a data item and a member function titled "name"), it is easy to see the similarities here. We don't have to use application to create a new frame in Python; the language takes care of that for us. The variable _name introduced in __init__ will be stored in a place accessible only to this object. self._name refers to the _name variable inside the object self; self is passed into any method of an object (we'll see how this works below.)
In the first line, we create a new my_object, passing it the value "bob" which will be stored as the _name value; this calls the classes __init__ method. Now, whenever we type obj.method(args), the member function of my_object is called with the first argument obj and the other arguments to the function appended in a frame where this objects variables are defined.obj = my_object("bob")
obj.name()
"Bob"
obj.my_object()
True
obj.say(["hello, world"])
hello, world
Python provides a convenient mechanism for inheritance:
ClassDefinition ::= class SubClassName ( SuperClassName ) :creates a new class named SubClassName that inherits from SuperClassName. Here's an example from PS6:
FunctionDefinitions
Scheme | Python |
---|---|
(define (make-lecturer name) (let ((super (make-object name))) (lambda (message) (if (eq? message 'lecture) (lambda (self stuff) (ask self 'say stuff) (ask self 'say (list "you should be taking notes"))) (get-method super message))))) |
class lecturer (my_object): def lecture(self, stuff): self.say (stuff) print "you should be taking notes" |
Because of Python's built in support for classes, object-oriented programs in Python are shorter and more elegant than object-oriented programs in Scheme.
The first line of the CGI file should be:
#!/uva/bin/pythonThis tells the web server that the rest of the file is a Python program that should be executed to produce the output page.
In order for the output to be interpreted as HTML, we need to print the content type at the beginning of the output:
print "Content-type:text/html\n"The \n prints a new line.
This assigns to form a dictionary of form values. For every form element with a name="Name" parameter in your HTML form, form will have a field with the name Name and assign it whatever data the user entered. We can access this with form["Name"].getvalue(). This extra getvalue() is required as opposed to a regular dictionary because of how CGI processes the form.
For the example form:
The file listed as ACTION= in the form will process the submitted form. Here's what formproc.cgi contains:<FORM METHOD="POST" ACTION="formproc.cgi">
First name: <INPUT TYPE="TEXT" NAME="FirstName"><BR>
Last name: <INPUT TYPE="TEXT" NAME="LastName"><BR>
Comments:<BR>
<TEXTAREA ROWS="3" NAME="UserComments"></TEXTAREA><BR>
<INPUT TYPE="SUBMIT"><INPUT TYPE="RESET">
</FORM>
#!/uva/bin/python import cgi print "Content-type:text/html\n" print "<html><head><title>Form Response</title></head>\n" print "<body>\n" form = cgi.FieldStorage() print "Thank you for your information!" print "<BR>" print "The keys are: " print form.keys () print "<p>" print "First name: " + form['FirstName'].value + "<br>" print "Last name: " + form['LastName'].value + "<br>" print "Comments: " + form['UserComments'].value + "<br>" print "</body></html>\n"
You can try it here:
|
Python provides procedures for interacting with a database using SQL. You can call these procedures like any other Python procedure. The Python evaluator will send the appropriate commands to the SQL database.
Before using any SQL commands, you'll want to connect to the database server and open a database. To tell Python we're going to be using a MySQL database, we begin the script with
import MySQLdb
Now you can connect to the database with your username and the password you created before, for example:
server = "dbm1.itc.virginia.edu"
username = "dee2b"
password = "quist"
dbName = "dee2b_presidents"
db=MySQLdb.connect(server, username, password, dbName)
In particular, dbm1.itc.virginia.edu is the hostname of ITC's database, username and password are those used to create your account, and dbName is the name of the database you created.
Now that we have a connection to the database we'll need a cursor to actually operate on it. Basically a cursor is just a way of keeping track of where you are in a table or result set. Getting a cursor from the database is simple:
cursor = db.cursor()
Now that we have a cursor to the database, we can execute queries, for instance:
college = "William and Mary" cursor.execute("""Select lastname, firstname from presidents where college=%s order by lastname""", (college,))
That last part, (college,) probably looks a little funny: this is simply because Python's database interface requires any parameters as a sequence. In general, if you know what you're looking for, you could insert it directly, for instance:
cursor.execute("""Select lastname, firstname from presidents where college='William and Mary'""")
Using %s lets us figure out something to look for based on a variable (for instance, a form field) rather than having to hard-code it. Now that we've executed the database query, if we did a SELECT statement, there are a few things we can do with the cursor:
db.commit()
At the end of your program, you can close the database connection with
db.close()
It's important to make sure you've committed the changes before closing, because otherwise the Python database interface will assume you didn't mean to make the changes and will perform a rollback - essentially undoing every change since the last commit.
Credits: This guide was created by David Faulkner, Dan Upton, and David Evans for CS150 Fall 2005. |