Second Summer 2009


Homework Assignment One
Homework One:

  1. carefully review the development outlined below, then
  2. state a similar problem and solve it in the same style.

  3. post your program, link to source code on your web server.

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:44063/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.

  #!/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.

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:
  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):

    %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

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

    <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 = ["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)
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 = 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:

  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."
Update the message if the answer is incorrect:

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

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

  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:

%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
Furthermore we need to tie seamlessly into the next game.

      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:44063/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:

  random.shuffle(names) 
You need to shuffle the array each time you initialize or re-initialize the code.

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.
B.2) Change the condition in the outer if to:

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

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

  if q.has_key("reset")    : reset     =     q["reset"].value
And we're done.


Updated by Adrian German for A202/A598