Contents:
1. Brief Summary of Last Couple of Weeks
We have met Unix and we have installed our first web server: Apache.
We know we need to put HTML pages in htdocs, and we know Perl scripts go in cgi-bin.
We've also developed the following programs in Perl.
a) simple calculator illustrating ==, =~, eq and split:
#!/usr/bin/perl
$balance = 0;
while (1 == 1) {
print "enter> "; # print the prompt
$line = <STDIN>;
if ($line =~ /quit/i) {
last;
} else {
($cmd, $arg) = split(/ /, $line);
if ($cmd eq "add") {
$balance += $arg;
} elsif ($cmd eq "sub") {
$balance -= $arg;
} else {
}
print "The balance is: $balance\n";
}
}
print "Thanks for using this program.\n";
b) variant of the calculator using almost exclusively the pattern matching:
#!/usr/bin/perl
$balance = 0;
while (1 == 1) {
print "type> ";
$line = <STDIN>;
if ($line =~ /deposit (\d+)/) {
$balance = $balance + $1;
} elsif ($line =~ /withdraw (\d+)/) {
$balance -= $1;
} else {
}
print "The balance is: $balance\n";
}
c) and a simple program that collects information in stages and reports a result:
Next we tried to implement this last program as a web script.#!/usr/bin/perl print "What is your name? \nType here: "; $name = <STDIN>; chop($name); print "Well $name how old are you?\nType your age here: "; $age = <STDIN>; print "OK $name, next year you will be ", ($age + 1), " years old.\n";
We had the following stages:
a) first we created an HTML form (nine.html) in htdocs:
<html>
<head><title>Age Calculation Form</title></head>
<body>
<form action="http://silo.cs.indiana.edu:46016/cgi-bin/0122/nine">
<table>
<tr> <td> Name: <td> <input type="text" name="who">
<tr> <td> Age: <td> <input type="text" name="age">
</table>
Push <input type="submit" value="Proceed"> to move on.
</form>
</body>
</html>
b) then we implemented this script (~/apache/cgi-bin/nine):
We discussed:#!/usr/bin/perl use CGI; $q = new CGI; print $q->header, $q->start_html; print $q->Dump; print $q->end_html;
Our next script (version of nine) looked like this:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$name = $q->param('who');
$age = $q->param('age');
print "Well $name you are going to be ", ($age + 1), " next year.";
print $q->end_html;
We made two comments:
action attribute in the form clearly identifies the target script
So we merged the interface with the script as follows:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$name = $q->param('who');
$age = $q->param('age');
if ($name) {
print "Well $name you are going to be ", ($age + 1), " next year.";
} else {
print qq{
<form action="http://silo.cs.indiana.edu:46016/cgi-bin/nine">
<table>
<tr> <td> Name: <td> <input type=text name=who>
<tr> <td> Age: <td> <input type=text name=age>
</table>
Press <input type=submit value=Proceed> to move on.
</form>
};
}
print $q->end_html;
The action attribute is no longer needed. When it's missing the browser sends the data to the address the form came from.
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$name = $q->param('who');
$age = $q->param('age');
if ($name) {
$age = $age + 1;
print qq{Well $name you will be $age next year.};
} else { # no data, print the form
print qq{
<form>
Name: <input type="text" name="who"> <br>
Age: <input type="text" name="age" size=4> <br>
Press <input type="submit" value="Proceed"> to move on.
</form>
};
}
print $q->end_html;
So now the host name, the port number and program name are all implicit. This was great but it wasn't able to collect the data in stages, the way our third Perl script did.
So we developed the following program:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$name = $q->param('who');
$age = $q->param('age');
if ($name) {
if ($age) {
$age = $age + 1;
print qq{ Well $name it looks like you will be $age next year.};
} else {
print qq{
<form>
Well $name <input type=hidden name=who value=$name> what is your age:
<input type="text" name="age">
<input type="submit" value="Send it!">
</form>
};
}
} else {
print qq{
<form>
Name: <input type="text" name="who"> <input type="submit" value="Send it!">
</form>
};
}
print $q->end_html;
This was a big accomplishment for us, if we realized it or not. For the first time we managed to keep state.
In hte basic layout:
if ($name) {
if ($age) {
# final report (age is input, name is remembered, as state)
} else {
# form to ask for age (prints name in question)
# (age is collected as input here, name turns into state)
}
} else {
# form to ask for name
# (name is collected as input here)
}
... we identified the following:
Recall how the form changed gradually.
1. First we had a form focused on getting the input:
2. Second we had a form that was able to send the name back to us:<form> Well $name what is your age: <input type="text" name="age"> <input type="submit" value="Send it!"> </form>
Basically at this stage we had the problem solved.<form> Well <input type=text name=who value=$name> what is your age: <input type="text" name="age"> <input type="submit" value="Send it!"> </form>
But we wanted to eliminate the possibility that the user may retype her/his name.
So we learned about hidden fields, and turned the text field into a hidden field.
3. This stage stores the name as hidden state, but leaves the user in the fog:
4. So we made one small change and obtained the final version:<form> Well <input type=hidden name=who value=$name> what is your age: <input type="text" name="age"> <input type="submit" value="Send it!"> </form>
As an exercise we asked if anyone could develop this program.<form> Well $name <input type=hidden name=who value=$name> what is your age: <input type="text" name="age"> <input type="submit" value="Send it!"> </form>
We emphasized this structure:
And realizing that we will have one state variable: balance, we implemented as much as we could.
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$number = $q->param('remember');
$proceed = $q->param('proceed');
if ($proceed) {
$number += 1;
} else {
$number = 0;
}
print qq{
<form>
<h1>$number</h1> <input type="submit" name="proceed" value="Add One">
<input type="hidden" name="remember" value="$number">
</form>
};
print $q->end_html;
This program was only half-working and the interface was a bit changed. But it was a serious accomplishment.
Finally, we also developed a program that was helping us select people:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
@names = ("Will", "Danielle", "Sujit", "Brenden", "Daniel",
"Kevin", "Andrey", "Michael", "Jon", "Adam", "Curtis",
"Adrian");
$input = $q->param('times');
for ($i = 0; $i < $input; $i++) {
$index = int(rand($#names + 1));
print $i, ". ", $names[$index], "<br>";
}
print $q->end_html;
That's all we did thus far. 2. Basic CGI Programming with Perl.
There are many places on the web where you can find information:
But it's enough to review what we wrote above.
Here's such a short summary written for this class a year or so ago.
3. Keeping State in CGI/Perl.
So far, the only way to keep state is with hidden fields, in HTML forms.
Keeping state when the input is via links is a more difficult proposition.
Here are some examples we looked at:
The program that plays cards is shown here.
No need to discuss it this week.
But the notes above do show the easiest way to post source code.
4. Case Study 1: The Counter Program
We have two cases:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$count = $q->param('count') + $q->param('add') + 0;
print qq{
<table border cellpadding=2>
<tr><td colspan=2 align=center> <h1>$count</h1>
<tr><td width=50% align=center> <a href="?count=$count&add=-1">Down</a> <td> <a href="?count=$count&add=1">Up</a>
</table>
};
print $q->end_html;
5. Case Study 2: The Addition Quiz Program Here's the code:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$score = $q->param('good');
$total = $q->param('total');
$message = $q->param('message');
$key = $q->param('key');
$answer = $q->param('amount');
if ($message) {
if ($key == $answer) {
$score += 1;
}
$total += 1;
} else {
$score = 0;
$total = 0;
}
$n1 = int(rand(100)) - 50;
$n2 = int(rand(100)) - 50;
$key = $n1 + $n2;
$message = "($score/$total) What is $n1 + $n2? ";
$me = $ENV{"SCRIPT_NAME"};
print qq{
<form>
$message <p>
<input type="hidden" name="good" value="$score">
<input type="hidden" name="total" value="$total">
<input type="hidden" name="message" value="$message">
<input type="hidden" name="key" value="$key">
Amount to add: <input type="text" name="amount"> <p>
<input type="submit" name="proceed" value="Click me!">
<a href="$me">Reset</a>
</form>
};
6. Case Study 3: The Shuffle Program
The program is listed as part of these notes (and alone, here).
7. Homework Two: The Flag Quiz (in CGI/Perl).
The homework will be discussed in lab in detail.
Here's a prototype, to look at.
8. Introduction to Python and CGI with Python.
We already had the Univ of Virginia tutorial.
9. Homework Two: The Flag Quiz (in CGI/Python).
There are detailed notes for this posted already.