Homework One: set up Apache. Homework Two: program that keeps state in CGI/Python or CGI/Perl. Homework Three: meant to be exposure to working with a database from a program. (See below). Homework Four: convert Homework Two to PHP with and without sessions. http://w3schools.com/php/ http://w3schools.com/php/php_post.asp http://w3schools.com/php/php_sessions.as Homework Five: in the program you wrote for Homework Two move state server-side. Where are you going to keep it? PHP does in in files. Should we use files? No. What do you mean by "No"? I mean I won't use it. I will use MySQL. In process we connect from a CGI/Python program to a database. And we can do that in PHP too. Homework Three: anything that makes Homework Five possible. You get Homework Three for free by doing Homework Five. You will create and populate, maintain and query one table. Today we solve Homework Five (and in the process meet the requirements for Homework Three). Take a look at this: http://www.cs.indiana.edu/classes/a348-dger/fall2004/notes/Eleven.html Also, please: http://www.cs.indiana.edu/classes/a348-dger/fall2004/notes/Ten.html So let's start: class Game(object): def __init__(self): self.clicks = 0 self.report() def play(self): self.clicks += 1 self.report() def report(self): print "Clicks is now:", self.clicks >>> ================================ RESTART ================================ >>> >>> brenden = Game() Clicks is now: 0 >>> ron = Game() Clicks is now: 0 >>> adrian = Game() Clicks is now: 0 >>> brenden.report() Clicks is now: 0 >>> brenden.play() Clicks is now: 1 >>> brenden.play() Clicks is now: 2 >>> brenden.play() Clicks is now: 3 >>> adrian.play() Clicks is now: 1 >>> brenden.play() Clicks is now: 4 >>> ron.play() Clicks is now: 1 >>> ron.play() Clicks is now: 2 >>> ron <__main__.Game object at 0x02947E30> >>> ron.report() Clicks is now: 2 >>> adrian <__main__.Game object at 0x02947F30> >>> adrian.report() Clicks is now: 1 >>> brenden.report() Clicks is now: 4 >>> Inheritance and dynamic method lookup. Now go into your ~/apache/cgi-bin and make a folder hwFive Create a file called template.py with this contents: import cgi #-------------------(this is template.py)-------------- class Engine(object): def __init__(self): # print "New engine created." self.input = cgi.FieldStorage() def execute(self): s = self.retrieveState() if s.isEmpty() or self.reset(): self.initializeState(s) else: self.updateState(s) self.saveState(s) self.reportState(s) self.getReadyforMoreInput() def retrieveState(self): return State() def initializeState(self, s): pass def saveState(self, s): pass def reportState(self, s): pass def getReadyforMoreInput(self): pass def reset(self): return False class State(object): def isEmpty(self): return True Save. Also in the same folder you should create a file called one with the contents: #!/usr/bin/python import template, random class One(template.Engine): def __init__(self): template.Engine.__init__(self) def retrieveState(self): # print "I am retrieving state..." (message, n1, n2, m1, m2) = ("", "", "", "", "") if self.input.has_key("message"): message = self.input["message"].value if self.input.has_key("n1"): n1 = self.input["n1"].value if self.input.has_key("n2"): n2 = self.input["n2"].value if self.input.has_key("m1"): m1 = self.input["m1"].value if self.input.has_key("m2"): m2 = self.input["m2"].value return MyState(message, n1, n2, m1, m2) def reset(self): reset = "" if self.input.has_key("reset"): reset = self.input["reset"].value return reset def initializeState(self, s): # print "I am being asked to initialize the state..." s.message = "Welcome" s.n1 = str(random.randrange(-50, 50)) s.n2 = str(random.randrange(-50, 50)) s.m1 = "0" s.m2 = "0" def updateState(self, s): # print "I am being asked to update the state based on input..." answer = "" if self.input.has_key("answer"): answer = self.input["answer"].value if answer and int(answer) == int(s.n1) + int(s.n2): s.message = "Very good." s.m1 = str(int(s.m1) + 1) else: s.message = "No, no, no." s.m2 = str(int(s.m2) + 1) s.message += "Score now: " + s.m1 + " out of " + s.m2 s.n1 = str(random.randrange(-50, 50)) s.n2 = str(random.randrange(-50, 50)) def saveState(self, s): print "
" print "" print "" print "" print "" print "" def reportState(self, s): print s.message + "

" print "What is " + s.n1 + " + " + s.n2 + "?" def getReadyforMoreInput(self): print "Answer:

" print "" print "" print "

" class MyState(template.State): def __init__(self, message, n1, n2, m1, m2): self.message = message self.n1 = n1 self.n2 = n2 self.m1 = m1 self.m2 = m2 def isEmpty(self): # print "I am being asked if I am empty..." return not self.message print "Content-type: text/html\n\n" # [1] one = One() # [2] one.execute() # [3] #------------------------(end of client side state driver)-------------- -bash-3.2$ ls -l total 16 -rw-r--r-- 1 dgerman faculty 2695 Oct 20 12:17 one -rw-r--r-- 1 dgerman faculty 715 Oct 20 12:11 template.py -bash-3.2$ chmod +x one -bash-3.2$ ls -l total 16 -rwxr-xr-x 1 dgerman faculty 2695 Oct 20 12:17 one -rw-r--r-- 1 dgerman faculty 715 Oct 20 12:11 template.py -bash-3.2$ Call one from the web: http://silo.cs.indiana.edu:8346/cgi-bin/hwFive/one So I want to change this to use a database instead to keep the state server side. Go to this page and learn how to do it: http://www.cs.indiana.edu/classes/a202-dger/sum2009/0708.txt Today we only go into MySQL and create a table: -bash-3.2$ cd /nobackup/dgerman/ -bash-3.2$ cd mysql-5.0.22/ -bash-3.2$ ls -ld step* -rwx------ 1 dgerman faculty 64 Oct 1 11:29 step006 -rwx------ 1 dgerman faculty 102 Oct 1 11:52 step007 -rwxr-xr-x 1 dgerman faculty 347 Oct 1 11:59 step008 -rwx------ 1 dgerman faculty 134 Oct 1 16:40 step010 -bash-3.2$ ls -ld conn* -rwx------ 1 dgerman faculty 105 Oct 13 12:26 connect_as_lbird -rwx------ 1 dgerman faculty 107 Oct 15 17:04 connect_as_mroth -rwx------ 1 dgerman faculty 82 Oct 1 12:10 connect_as_root -bash-3.2$ ./connect_as_lbird Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 14 Server version: 5.0.22-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> use awards Database changed mysql> show tables; Empty set (0.00 sec) mysql> edit UW PICO(tm) 4.10 File: /tmp/sqlenjmPg Modified create table hwFive ( session_id char(8) primary key, message varchar(240), n1 int, n2 int, m1 int, m2 int, modified timestamp ); [ Wrote 10 lines ] -> ; Query OK, 0 rows affected (0.06 sec) mysql> describe hwFive; +------------+--------------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+-------------------+-------+ | session_id | char(8) | NO | PRI | | | | message | varchar(240) | YES | | NULL | | | n1 | int(11) | YES | | NULL | | | n2 | int(11) | YES | | NULL | | | m1 | int(11) | YES | | NULL | | | m2 | int(11) | YES | | NULL | | | modified | timestamp | YES | | CURRENT_TIMESTAMP | | +------------+--------------+------+-----+-------------------+-------+ 7 rows in set (0.00 sec) mysql> exit Next time we simply extend this program providing two methods only: a) retrieve state (from the database) and b) save state (into the database). They may need additional helpers but they will completely shadow the methods from the superclass that were using hidden fields. --