Welcome to the notes, summary, review and guidelines for Homework Two.

This is the third installment of this type of notes. Two down (4, 6), two more to go (5, 7).

I hope you're going through these notes in the order I wrote them: 4, 6, now 2, then 5 and 7.

This problem asks that we solve the Flag Quiz using CGI and either Perl or Python.

I suggest we use Python with hidden fields (Homework Two) and Perl for Homework Five.

As you recall, Homework Five is a variant of Homework Two where state is kept server-side (instead of client-side).

As far as the problem per se, we all know it: it's described in the text on page 32.

The text is the .pdf we have been using since the beginning of the semester:

http://www.cs.indiana.edu/~dgerman/eowp06.pdf
The state needs to be kept client-side for this homework assignment.

Images are located in the same place:

http://silo.cs.indiana.edu:11350/images/
Every time we work out a problem like this we can apply our template.

First step is to determine what our state is made of.

The following are immediate candidates (as we already know):

The inputs also need to be discussed:

So I guess we have what we need to get started.

Let's do this in Python, and trying to match our Homework Four (PHP) development.

  <?

   ?>

  <form>

  </form>
  #!/usr/bin/python

  print "Content-type: text/html\n\n"

  print """
    <form>    
  
    </form>
  """

Basically this includes a code portion, along with a "get ready for more input" portion.

So we see more needs to be done in Python to get the same thing(s) done.

As a matter of fact the following also need to be added:

a) load the module that implements the common gateway interface:

import cgi
b) create an object that contains the incoming data, parsed:

q = cgi.FieldStorage()
c) initialize the five state variables and one input variable:

(message, questions, key, correct, total, answer) = ("", "", "", "", "", "")
d) read their values (retrieve state, read input):

if q.has_key("message")  : message   =   q["message"].value
if q.has_key("questions"): questions = q["questions"].value
if q.has_key("key")      : key       =       q["key"].value
if q.has_key("correct")  : correct   =   q["correct"].value
if q.has_key("total")    : total     =     q["total"].value
if q.has_key("answer")   : answer    =    q["answer"].value
We sketch more of the basic layout:

  if ($message) {
    
  } else {
    $message = "Welcome to the game, are you ready?"; 
  } 
if message:
  pass
else:
  message = "Welcome to the game, are you ready?"

We also enhance the content of the form as well (as expected the code on the right is partial):

  <?=$message?> <p>
  
  Press <input type="submit" value="Proceed"> to move on. 
  <input type="hidden" name="message" value="<?=$message?>"> 
    %s <p>
  
    Press <input type="submit" value="Proceed"> to move on.
    <input type="hidden" name="message" value="%s">           
  </form>
""" % (message, message)

Obviously, we are just acknowledging the initialization of $message.

Perhaps this would be a good time to approach state initialization in general:

    $correct = 0; 
    $total = 0; 
    $questions = "Italy," . 
                 "Australia," . 
                 "United States," . 
                 "South Africa," . 
                 "Spain,China," . 
                 "Russia," . 
                 "Brazil"; 
    $key = ""; // there is no key in the beginning
  correct = 0
  total = 0
  questions = "Italy," + \
              "Australia," + \
              "United States," + \
              "South Africa," + \
              "Spain," + \
              "China," + \
              "Russia," + \
              "Brazil"
  key = "" # there is no key in the beginning

Let's decide to save the state on the client side:

  <input type="hidden" name="correct"   value="<?=$correct?>">
  <input type="hidden" name="total"     value="<?=$total?>">
  <input type="hidden" name="questions" value="<?=$questions?>">
  <input type="hidden" name="key"       value="<?=$key?>">
    <input type="hidden" name="questions" value="%s">
    <input type="hidden" name="key"       value="%s">
    <input type="hidden" name="correct"   value="%s">
    <input type="hidden" name="total"     value="%s">

In Python this is a two-step process, the second part of which includes:

""" % (message, message, questions, key, correct, total)

Now let's make some changes. Add (at the top of the code part) these definitions:

  $url = "http://www.cs.indiana.edu/classes/a202-dger/fall2005/notes/flagquiz/images";
  
  $names = array ("Australia", "United States", "Russia", "Spain", "Italy", "South Africa", "Brazil", "China");

This was in PHP, in Python that becomes:

  url = "http://www.cs.indiana.edu/classes/a202-dger/fall2005/notes/flagquiz/images"
  
  names = ["Australia", "United States", "Russia", "Spain", "Italy", "South Africa", "Brazil", "China"]

We really need the square brackets here, the round ones won't do, you will see why.

Also modify the line that initializes $questions too:

    $questions = join(",", $names);
That was in PHP, in Python it becomes:

     questions = ",".join(names)
This way we leave ourselves open to the idea of shuffling, initially.

We should now take care of the user submissions coming after the initial screen.

    if ($key) {
      if ($answer == $key) {
        $correct += 1;
      } else {
    
      }
      $total += 1;
    } else {
     
    }
In Python that becomes:

  if key:
    if answer == key:
      correct = str(int(correct) + 1)
    else:
      pass
    total = str(int(total) + 1)
  else:
    pass
Next we need to grab the answer key that follows from the remaining questions:
    list($key, $questions) = split(",", $questions, 2); 
In Python that becomes:

  names = questions.split(",")
  (key, questions) = (names[0], ",".join(names[1:])) 
At the same time we need to update the message, and be ready to ask questions. So we have:

Update the message if the answer is correct:

  $message = "Very good."; 
In Python that becomes:

  message = "Very good."
Update the message if the answer is incorrect:

  $message = "No, that was not it."; 
In Python that becomes:

  message = "No, that was not it" 
Update the message with the new values of the score:

  $message .= " Score currently: $correct out of $total."; 
In Python that becomes:

  message += " Score currently: " + correct + " out of " + total + "."
Prepare the question you want to ask:

  $question = "Whose country is this flag: <img src='$url/$key.png'> <input type=text name='answer'> <p>";    
In Python that becomes:

  question = "Whose country is this flag: <img src='%s/%s.png'> <input type=text name='answer'> <p>" % (url, key)
Show the question and get ready for (more) user input:

  <?=$question?>
In Python that becomes:

%s
... followed (in the right place) by something like this:
""" % (message, question, ...
Also, don't forget to initialize question so you can show it on the first screen:

  ... answer, question) = ("", "", "", "", "", "", "")   
Now the program works almost as intended, except at the end of the quiz.

So we need to not ask a new question if we are not able to:

    if ($questions) {
      // ... 
    } else {
      $question = "The game has ended, new game starting, are you ready? <p>";
      $correct = 0;
      $total = 0;
      $questions = join(",", $names);
      $key = ""; // there is no key in the beginning
    }
In Python that becomes:

    if questions: 
      # ... 
    else:
      question = "The game has ended, new game starting, are you ready? <p>";
      correct = 0;
      total = 0;  
      questions = ",".join(names)
      key = ""; # there is no key in the beginning
Furthermore we need to tie seamlessly into the next game.

      $message = "Welcome to a new game, score currently: $correct out of $total."; 
In Python that becomes:

      message = "Welcome to a new game, score currently: " + correct + " out of " + total + "."
That goes into a previously empty branch of the program.

This is what we have obtained:

      http://silo.cs.indiana.edu:11350/cgi-bin/1118/one  
What remains to be done:

These are very simple things.

A. To shuffle the array you need to invoke the following with each initialization:

  shuffle($names); 
You can check with php.net on the use of shuffle.

You need to shuffle the array each time you initialize or re-initialize the code.

In Python that becomes:

  random.shuffle(names) 
Of course, you also need this:

  import random 
B. To add a reset button you do two things:

B.1) Add the button to the form:

Press <input type="submit" name="reset" value="Reset"> to reset the game.
In Python that is entirely identical.

B.2) Change the condition in the outer if to:

if ($message && ! $reset) {
In Python that becomes:

if message and not reset: 
Also, this, again:

  ... answer, question, reset) = ("", "", "", "", "", "", "", "")  
And:

  if q.has_key("reset")    : reset     =     q["reset"].value
C. Finally, to switch from client-side state to server-side state: becomes Homework Five (soon to come).
Last updated on Nov 17, 2008, by Adrian German for Essentials of Web Programming