Activities for Lab 5
Solutions

CGI and HTML

1. Create an HTML page (/lab5/one.html) that contains a form that asks the user for her/his name and password. Use one password field and one text field. Ignore, if you want, the method and action fields but provide a submit and a reset button on the form).

This part was easy, basic HTML.

2. Create an HTML page (/lab5/two.html) that contains one form that calls the /cgi-bin/printenv script on your server. The form itself should contain three multiple-choice questions: a RADIO question, a SELECT question, and a CHECKBOXES question. Use GET as the request method in your form. Provide submit and reset buttons. Call up the page with Netscape, fill in the form and submit it. Look at the script's output. Do the same thing with POST. What are the differences in the script's output, if any?

$ENV{'QUERY_STRING'} was the difference

The URL is longer when you call with GET.

Remember the menu program.

3. Write a script (/cgi-bin/lab5/three) that uses CGI.pm and prints 'Howdy World' to the screen.

This was covered in Lecture 7

Documentation for CGI.pm is in this page under the heading Lincoln Stein's CGI.pm.

Here's the answer in blue:


#!/usr/bin/perl
use CGI;
$query = new CGI;

print $query->header, 
      $query->start_html (-bgcolor=>'white', 
                          -title=>'Hello World'); 
      
print "<em>Howdy world!</em>"; 

print $query->end_html;  

4. Write a script (/cgi-bin/lab5/four) that uses CGI.pm that prints out the form developed at step 2 when called with GET and $query->dump when called with POST.

Here's the script (the blue was missing):
#!/usr/bin/perl
use CGI;
$query = new CGI;
print $query->header, 
      $query->start_html (-bgcolor=>'white', 
                          -title=>'Some Echo');  
if ($query->request_method eq 'GET') {
  &show_form; # simply writes out a form  
} elsif ($query->request_method eq 'POST') {
  print $query->dump; 
} 
print $query->end_html; 
5. Copy /lab5/one.html into /lab5/five.html and change the action field in the form to the script developed at step 4. You now have two entry points in the script. How many more can you have/create?

You can have as many as files that contain that form you can create. This is an aspect you need to be aware of because that's what makes CGI programming different from any other kind of programming: there is no direct continuous connection, instead the user and the server go through stages of processing, much like in a conversation.

This is important because it means that the user can basically start off in any point in your flow diagram.

This is really important because you can't do it with conventional programming tools, at least not easily, and it requires a special way of thinking.

6. Run the script developed at step 4 from the command line. Does anything strike you as being a useful aspect of CGI.pm compared to the way we developed the menu and calculator programs?

It asks you for input. You can specify pairs (name=value) of parameters and end the stream with control-D (EOF). That's so much more useful than the way we described debugging methods for menu and calculator.

Perl

7. Write a Perl program that lists its command line arguments.

Here's part of it to get you started:

foreach $val (@ARGV) { 
or
for ($i = 0; $i <= $#ARGV; $i++) { 
Make the program write its output in both ways.

This is program six in Lecture 3.
8. Write a Perl program that reads one line from the terminal and prints it back surrounded by ***( and ***). Use chop, if you need to. Make the output appear on a line of its own.

Here's the solution, your contribution in blue:

#!/usr/bin/perl
$x = <STDIN>; 
chop($x);
print "***( ", $x, ")***\n"; 
 
9. Write a Perl program that reads a file and prints only its even numbered lines. Change the program to print all the lines each line in the output being preceded by its number. Assume the first line in the file has number 1. It's up to you how you make the name of the file known to your program.

Here are the solutions, your contributions in blue:

#!/usr/bin/perl
open (AB, "myfile");  
@x = <AB>;
close(AB); 
foreach $line (@x) {          # for each line 
  $count += 1;                # $count is its number 
  if ($count % 2 == 0) {
    print $count, ": ", $x;   # unchopped  
  } 
} 
 
You knew this from the Fibonacci program in the Java lecture.
Do it whis way too:
#!/usr/bin/perl
open (AB, "myfile"); 
while ($x = <AB>) {
  $count += 1;                # $count is its number 
  if ($count % 2 == 0) {
    print $count, ": ", $x;   # unchopped  
  } 
} 
close(AB); 
 
Explain the differences between the two approaches.

Much of each is unchanged. The difference is that we can get the whole file in one fell swoop or line by line.

It's the context in which we use the angle brackets (<AB>).

Getting the lines one by one is perhaps slower by takes up less memory (think of what $#x is when the file is large).

10. Modify the program from step 9 that numbers lines such that the name of the input file is specified on the command line preceded by a switch -file.

Here's the solution, your contribution in blue:

#!/usr/bin/perl 
if ($ARGV[0] eq "-file" && $ARGV[1]) {
  open (AB, $ARGV[1]);
  while ($x = <AB>) {
  $count += 1;                # $count is its number 
  if ($count % 2 == 0) {
    print $count, ": ", $x;   # unchopped  
  } 
} 
close(AB); 
 
All of the blue code comes from program 9, so essentially the hint for 10 was the answer for it (because the rest of the code was coming from problem 9, in one of its incarnations).
Java

Both programs appear in Lecture 6
10. Implement the Echo program in Java and run it from the command line and run it from the command line with various inputs.

Here's part of it to get you started:

public class Echo {
  public static void main (String[] args) {
    int i=0; 
    while (i < args.length) {
      System.out.print (args[i] + " ");
11. Implement Echo in reverse in Java too.

Here's part of it to get you started:

for (int i = args.length - 1; i >= 0; i--) {
  for (int j=args[i].length() - 1; j >= 0; j--) {
    System.out.print(args[i].charAt(j));