roy > naoya > 基礎プログラミングII > (9)複雑なCGI

(9) :複雑なCGI

[1]複雑なCGI

複数ページを1つのプログラムで作る

次のCGIを試してみよう。

迷路から脱出せよ

これは迷路の中を進んでゴールにたどり着くゲームの簡略版である。何度も進路を選択して進んでいき、最終的にゴールにたどり着くが、このようなページは単一のプログラムで書くことができる。プログラムを見てみよう。

#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"

number = c["rd"]

if number == ""  #初回起動時のみ
 number = "1"    #numberに"1"を代入
end

if number != "7" #numberが"7"以外の場合は(7はゴール)

 print"<html><head><title>クイズ</title></head><body>\n"
 #formタグやOKボタンは1つで共用
 print"<form method=\"POST\" action=\"./sample.rb\">\n"
 if number == "1"
   print"<p>どっちへ進む?</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"2\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"3\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"5\">上\n"
 elsif number == "2"
   print"<p>さてどうしよう</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"3\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"5\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"6\">上\n"
 elsif number == "3"
   print"<p>だんだんわからなくなってきたぞ。次はどうする?</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"1\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"2\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"5\">上\n"
 elsif number == "4"
   print"<p>ゴールが近づいてきたような気がする</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"2\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"1\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"7\">上\n"
 elsif number == "5"
   print"<p>だめだどこにいるかわからない</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"2\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"6\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"1\">上\n"
 elsif number == "6"
   print"<p>ここはどこだろう</p>\n"
   print"<input type=\"radio\" name=\"rd\" value=\"3\">右\n"
   print"<input type=\"radio\" name=\"rd\" value=\"4\">左\n"
   print"<input type=\"radio\" name=\"rd\" value=\"5\">前\n"
   print"<input type=\"radio\" name=\"rd\" value=\"2\">上\n"
 end

 print"<input name=\"ok\" type=\"submit\" value=\"送信\">\n"
 print"<input name=\"ng\" type=\"reset\" value=\"リセット\">\n"
 print"</form>\n"
else
 print"<p>おめでとう! ゴールです</p>\n"
end
print "</body>\n"
print "</html>\n"

選択したラジオボタンのvalueの値に応じて、if文で異なるメッセージが表示されるようになっている。

値を次の次に引き渡す

5問のクイズを1ページに1つずつ出題する場合、最初の問題や2つ目の問題に対する回答を最終ページに持ち越すことは通常はできない。しかし、<input type="hidden">を使うと持ち越すことができる。

次の次のページにデータを引き渡す

#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"


data = c["rd"]
hoge = c["dat"]

hoge << data      #直前に選んだデータをhogeに追加

hogehoge = hoge.split(",")  #hoge内のデータを,ごとに配列に分割


print"<html><head><title>好きな果物</title></head><body>\n"


print"<form method=\"POST\" action=\"./sample2.rb\">\n"
print"<p>ひとつ選択</p>\n"
print"<input type=\"radio\" name=\"rd\" value=\"りんご,\">りんご\n"
print"<input type=\"radio\" name=\"rd\" value=\"バナナ,\">バナナ\n"
print"<input type=\"radio\" name=\"rd\" value=\"みかん,\">みかん\n"
print"<input type=\"hidden\" name=\"dat\" value=\"#{hoge}\"><br>\n"
    #type="hidden"で入力パーツを表示せず、hogeをプログラムに引き渡す
print"<input name=\"ok\" type=\"submit\" value=\"送信\">\n"
print"<input name=\"ng\" type=\"reset\" value=\"リセット\">\n"
print"</form>\n"


print"<p>選んだもの</p>"
for i in hogehoge
  printf("<p>%s</p>",i)
end



print "</body>\n"
print "</html>\n"

print"<input type=\"hidden\" name=\"dat\" value=\"#{hoge}\"><br>\n"の部分で、typeをhiddenとしているため入力用のパーツは何も表示させずに、データをプログラムに引き渡すことができる(ここではkeyがdat、valueを変数hoge)。

splitメソッドは変数.split(区切り)という形式で用いることで区切りの位置で変数内の値を区切って配列に変換することができる。今回のケースでは、hogeは通常変数であり、この変数内には"りんご,バナナ,バナナ,みかん"のように文字列が,を挟んで合体したような形で代入されている。これをsplitメソッドを使ってカンマの位置で切ることで、hogehogeは["りんご","バナナ","バナナ","みかん"]のようになる。なお変数hogeで各果物の間にカンマがついているのはラジオボタンのvalueの部分でvalue=\"バナナ,\"のようにカンマをつけているためである。

[2]自由課題グループ分け

次回から自由課題実施期間となる。これまで学んできたことを駆使してグループごとにプログラムを作成する。5~6人のグループを作る。これまでに獲得してきた点数に基づき、各グループの戦力が均衡するようにグループ分けを行う。どのようなプログラムを作成するか考えておくと良い。

[3]レポート課題

問題(10点満点):CGIを使って自由に何かを作成する。10点満点だが、単に授業用のページ(他の先生も含む)に掲載されているものを複写し、多少言葉を変えただけの場合はプログラム点の配点を最低点とする。


  • 提出先:課題提出用メールアドレス
  • 提出期限:第1提出期限、第2提出期限を設定
  • メールのSubject:課題7
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降は下記の構成とする
  1. データを入力するWebページのURL
  2. 作成したプログラム(CGIスクリプト)
  3. プログラムの説明
  4. 感想

  • 採点基準:期限内提出点(2点)、メールの体裁(1点)、プログラム(1~5点)、説明(2点)
  • プログラムの説明:何をするCGIなのか、Webページの入力フォームから受け取った値をどのように処理しているのかについて
  • わかりにくい説明や、Webページを単にコピー&ペーストしただけの説明は減点することがある。一度読み直してから提出すること。
  • 驚異的に良くできているレポートについては満点を超える得点をつけることがある。
  • よくできていたレポートは、他の人の参考になるよう、本人が特定できないような形で掲載する。掲載してほしくない場合はメールでの課題提出時にその旨記載すること。

Tips:emacsでの日本語入力のオンオフはCtrl-oです

Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする

Tips:Mewによるメールの送り方はMewコマンドを参照