(11) 12/18の授業内容:CGI[2]

trr

授業開始10分後より20分間、trrの試験を行う。150点で1点。以降25点ごとに1点加点で、最大5点まで。つまり250点以上は何点でも5点となる。

出席、レポート、trrの合計得点により試験免除者を決定する。発表は1月に入ってからであり、出席は免除者発表の直前までの状況を全て加味する。未提出のレポートがある場合は早めに提出すること。また、採点結果が戻ってきていない課題がある場合は今年中に申し出ること。

出席課題

念のために、この20分間でマークしたtrrの最高得点を連絡する。

制限時間は5分。出席点は2点。提出要領は下記の通り。

  • 提出先:naoya@e.koeki-u.ac.jp
  • メールのSubject:ruby11
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目に得点を記載し、その他感想等があれば記載する。

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

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

CGIの復習

CGIを作成するためには幾つかのルールがあった。この点についてまずはまとめてみよう。

  1. public_htmlの中にcgi専用のディレクトリ(例えばcgi-bin)を作る。以下で作成する3つのファイルはいずれもこのディレクトリに保存する。
  2. このディレクトリでcgiを利用するという宣言を記述した.htaccess(ファイル1)を作成する。
  3. ユーザがデータを入力するためのHTML文書(xxx.html)を作成する。
  4. 入力したデータを受け取って処理をして結果出力用のHTML文書を生成するCGIスクリプト(xxx.rb)を作成する。
  5. Rubyで書かれたCGIスクリプトを自分以外の人でも実行できるように、アクセス権を与える。

CGIを利用するためのディレクトリcgi-binをpublic_htmlの中に新たに作成するためには、public_htmlのディレクトリにcdコマンドで移動してから、ディレクトリ新規作成コマンドのmkdirを使用する。

irsv{c10xxxx}% cd public_html[Return]
irsv{c10xxxx}%  mkdir cgi-bin[Return]

.htaccessの記述内容は以下の通り。emacsで作成する際に、File:~/public_html/cgi-bin/.htaccessとする。以下の2行を記入して保存する。

AddHandler cgi-script   .rb
Options  +ExecCGI

HTML文書の一例を以下に示す(form.html)。←このファイル名の部分がハイパーリンクになっているので、右クリックして「Save Link As」を選択し、public_html/cgi-binの中に保存する。

氏名:
個数を選択:
 鉛  筆(100円):
 消しゴム(100円):
 ノート (150円):
 ファイル(300円):
 蛍光ペン(120円):

以下はCGIスクリプトの例である。kakaku.rbという名前をつけて保存する。cgi-binの中に保存するため、emacsで新規作成する場合、File:~/public_html/cgi-bin/kakaku.rbとなる。

#!/usr/bin/env ruby

require 'cgi'
c = CGI.new("html4")
print "Content-type: text/html; charset=EUC-JP\n\n"

name = c["name"]
var1 = c["pencil"]
var2 = c["eraser"]
var3 = c["note"]
var4 = c["file"]
var5 = c["pen"]

sum1 = 100 * var1.to_i
sum2 = 100 * var2.to_i
sum3 = 150 * var3.to_i
sum4 = 300 * var4.to_i
sum5 = 120 * var5.to_i

sum = (sum1 + sum2 + sum3 + sum4 + sum5) * 1.05

print "<html>
<head><title>お会計</title></head>
<body>\n"

print "<h1>#{name}さんのお会計</h1>\n"

print "<p>鉛  筆が#{var1}個で#{sum1}円</p>\n"
print "<p>消しゴムが#{var2}個で#{sum2}円</p>\n"
print "<p>ノート が#{var3}個で#{sum3}円</p>\n"
print "<p>ファイルが#{var4}個で#{sum4}円</p>\n"
print "<p>蛍光ペンが#{var5}個で#{sum5}円</p>\n"
print "<p>税込み合計で#{sum.to_i}円です。</p>\n"
print "</body>\n"
print "</html>\n"

保存後には、CGIスクリプトとして実行できるようにするため、ktermで以下を入力すること。
irsv{c10xxxx]% chmod 755 kakaku.rb[Return]もしくは
irsv{c10xxxx]% chmod +x kakaku.rb[Return]

これら全ての手順を抜け落ちなく実施すると

http://roy.e.koeki-u.ac.jp/~c10xxxx/cgi-bin/form.html

で入力フォームが表示され、適宜入力してOKを押すと何らかの結果が出るはずである。

CGI実行時のエラーメッセージ

表示されるエラーメッセージの内容によって、エラー内容を概ね特定することができる。

ブラウザに入力フォームのURLを入力するとNot Foundと表示される。

URLが間違っている。URLはhttp://roy.e.koeki-u.ac.jp/~c10xxxx/cgi-bin/yyyy.htmlとなる。xxxxは自分の学籍番号(チェックディジットなし)、yyyは作成した入力フォームのファイル名となる。

上記の通り正しく入力している場合は、入力フォームのファイルを保存した場所がそもそも間違っている。ktermでcgi-binのディレクトリに移動し、lsを入力して作成したファイルがあるかどうか確認する。

入力フォームに入力しOKを押すとPermission Deniedと表示される。

.htaccessファイルを作成していない。作成したが保存できていない。

CGIスクリプト(Rubyプログラム)のアクセス権を変更していない

入力フォームに入力しOKを押すとInternal Server Errorと表示される。

CGIスクリプト(Rubyプログラム)の書き間違え。変数名の入力間違いがないか確認しよう。

入力フォームに入力しOKを押すと真っ白な画面になる。

CGIスクリプト(Rubyプログラム)の書き間違え。変数名の入力間違いがないか確認しよう。

データ入力用HTML文書の構成

HTML言語を使用したWebページの記述方法については、1年生の情報リテラシーIIで実施済みである。ここでは入力フォームの作り方について確認する。

冒頭で示した入力フォームとそのソースを見てみよう。

氏名:
個数を選択:
 鉛  筆(100円):
 消しゴム(100円):
 ノート (150円):
 ファイル(300円):
 蛍光ペン(120円):

<form method="POST" action="./kakaku.rb">
<p class="item">氏名:
<input type="text" name="name" maxlength="40"><br>
個数を選択:<br>
 鉛  筆(100円):<select name="pencil">
  <option> 0
  <option> 1
  <option> 2
  <option> 3
 </select><br>
 消しゴム(100円):<select name="eraser">
  <option> 0
  <option> 1
  <option> 2
  <option> 3
 </select><br>
 ノート (150円):<select name="note">
  <option> 0
  <option> 1
  <option> 2
  <option> 3
 </select><br>
 ファイル(300円):<select name="file">
  <option> 0
  <option> 1
  <option> 2
  <option> 3
 </select><br>
 蛍光ペン(120円):<select name="pen">
  <option> 0
  <option> 1
  <option> 2
  <option> 3
 </select><br>

<input name="ok" type="submit" value="OK">
<input name="ng" type="reset" value="reset">
</p>
</form>

ソースを見ると、入力フォームは、form要素(<form>タグ)を使って書かれていることがわかる。form要素の基本構造は

<form method="メソッド" action="./スクリプト">


</form>

となる。メソッドの部分はGETまたはPOSTのどちらかを指定する。GETは最大で255文字までしか送ることができない(今回は名前と商品の購入数があるが、これらを全て含めて255文字)。項目数が多い場合や長い文章を入力させる場合はPOSTを指定する。ここではPOSTを使うものとして説明を続ける。

スクリプトの部分は入力データの引渡し先である。このソースを見ると、./kakaku.rbとなっており(./は同一ディレクトリをあらわすので)、cgi-binディレクトリの中にあるkakaku.rbがデータを受け取って処理をしていることがわかる。

このformの例では、

  • nameという名前の最大40文字の文字列
  • pencilという名前で0、1、2、3のいずれか
  • eraserという名前で0、1、2、3のいずれか
  • noteという名前で0、1、2、3のいずれか
  • fileという名前で0、1、2、3のいずれか
  • penという名前で0、1、2、3のいずれか

をそれぞれ受け取り、kakaku.rbに引き渡していることがわかる。

CGIスクリプト(Rubyプログラム)の構成

CGIスクリプトとなるRubyプログラムでは、まず冒頭で必ず以下を記述する。

#!/usr/bin/env ruby

require 'cgi'
c = CGI.new("html4")
print "Content-type: text/html; charset=EUC-JP\n\n"

1行目は必ず記述するおまじないであるが、CGIスクリプトを書く場合は通常とは異なるので注意しよう。

c = CGI.new("html4")で、HTMLの入力フォームから引き渡された値が、変数cにハッシュ値として代入される。変数cはどんな名前にしても構わない。

cにハッシュ値として代入されていることから、各入力値を取り出すためには、HTMLが引き渡す際に設定したnameやpencilをkeyとするvalueという形で指定すればよい。

例えば

var1 = c["pencil"]

とすれば、keyのpencilに対応するvalueがvar1に代入される。

以下は、上記の入力フォームに入力後、HTMLが引き渡すRubyプログラム(kakaku.rb)である。

注意
このRubyプログラムは、~/public_html/cgi-bin/の中に保存すること。
保存後には、CGIスクリプトとして実行できるようにするため、ktermで以下を入力すること。
irsv{c10xxxx]% chmod 755 kakaku.rb[Return]もしくは
irsv{c10xxxx]% chmod +x kakaku.rb[Return]

#!/usr/bin/env ruby

require 'cgi'
c = CGI.new("html4")
print "Content-type: text/html; charset=EUC-JP\n\n"

name = c["name"]
var1 = c["pencil"]
var2 = c["eraser"]
var3 = c["note"]
var4 = c["file"]
var5 = c["pen"]

sum1 = 100 * var1.to_i
sum2 = 100 * var2.to_i
sum3 = 150 * var3.to_i
sum4 = 300 * var4.to_i
sum5 = 120 * var5.to_i

sum = (sum1 + sum2 + sum3 + sum4 + sum5) * 1.05

print "<html>
<head><title>お会計</title></head>
<body>\n"

print "<h1>#{name}さんのお会計</h1>\n"

print "<p>鉛  筆が#{var1}個で#{sum1}円</p>\n"
print "<p>消しゴムが#{var2}個で#{sum2}円</p>\n"
print "<p>ノート が#{var3}個で#{sum3}円</p>\n"
print "<p>ファイルが#{var4}個で#{sum4}円</p>\n"
print "<p>蛍光ペンが#{var5}個で#{sum5}円</p>\n"
print "<p>税込み合計で#{sum.to_i}円です。</p>\n"
print "</body>\n"
print "</html>\n"

このプログラムでは、上半分でHTMLより送られた値をname、var1、var2、var3、var4、var5、var6に代入し、sum1〜sum5、sumを計算している。

下半分では、結果をHTML形式で出力するために<html>や<body>、<p>などのタグをprintを使って記述している。

プログラムの下部にある#{・・・}という記法は、その部分をRubyの式をしてその値に置き換える働きを持つ。例えば、

print "10+20は#{10+20}です\n"

とすると

10+20は30です

と表示される。また、

x=30
print "10+20は#{x}です\n"

とすると

10+20は30です

と表示される。

CGIスクリプトの応用(処理の切替)

これまで、入力した値に基づいて計算を行って結果を表示するCGIスクリプトについて見てきたが、今度は一歩進んで、入力した値により出力を切り替える例を作成してみよう。つまりif文を用いて結果を切り替える。

氏名:
性別: 男性 女性 どちらでもない
以下の各項目について当てはまるものに全てチェックをつけてください。
いろいろ勉強して自分を深めたい
社会に出て成功したいと思う
いつも何か目標を持っている
手がけたことは最善を尽くしたい

今回はラジオボタン(これ→)やチェックボックス(これ→)が追加されている。これらのパーツはいずれもいずれもinput要素で作成できる。パーツの使い分けはtype属性で指定する。

  • type="text":1行の入力フィールド
  • type="radio":ラジオボタン
  • type="checkbox":チェックボックス
  • type="submit":送信ボタン
  • type="reset":リセットボタン

shinri.html

<form method="POST" action="./shinri.rb">
<p class="item">氏名:
<input type="text" name="name" maxlength="40"><br>
性別:
<input type="radio" name="rd" value="男性">男性
<input type="radio" name="rd" value="女性">女性
<input type="radio" name="rd" value="不明">どちらでもない<br>
以下の各項目について当てはまるものに全てチェックをつけてください。<br>
<input type="checkbox" name="box1" value="1">
いろいろ勉強して自分を深めたい<br>
<input type="checkbox" name="box2" value="1">
社会に出て成功したいと思う<br>
<input type="checkbox" name="box3" value="1">
いつも何か目標を持っている<br>
<input type="checkbox" name="box4" value="1">
手がけたことは最善を尽くしたい<br>

<input name="ok" type="submit" value="OK">
<input name="ng" type="reset" value="reset">
</p>
</form>

以下は、上記のHTMLからの入力データを受け取り、処理をして結果のHTML文書を出力するCGIスクリプトであるshinri.rbである。先ほどと同様に変数cのハッシュ値として入力値を取り出し、チェックをした項目数に応じてif文でメッセージを変化させていることがわかる。

shinri.rb

#!/usr/bin/env ruby

require 'cgi'
c = CGI.new("html4")
print "Content-type: text/html; charset=EUC-JP\n\n"

namae = c["name"]
seibetsu = c["rd"]
q1 = c["box1"]
q2 = c["box2"]
q3 = c["box3"]
q4 = c["box4"]

point = q1.to_i + q2.to_i + q3.to_i + q4.to_i

print "<html>
<head><title>診断結果</title></head>
<body>\n"

print "<h1>#{namae}さん(#{seibetsu})の診断結果</h1>\n"

print "<p>あなたがチェックをした項目数は#{point}個です。</p>\n"

print "<p>"
if point == 4
  print "やる気満々ですね。このまま頑張って!\n"
elsif point == 3
  print "結構頑張り屋さんですねえ。この調子で。\n"
elsif point == 2
  print "うーん。まあまあですかねえ\n"
elsif point == 1
  print "うーん。うーん。もうちょっとやる気見せましょう。\n"
else
  print "やる気ないですね。\n"
end
print "</p>\n"
print "</body>\n"
print "</html>\n"

さらに発展する

入力部品の構成部品について

CGIのサンプル

レポート課題

以下のうちいずれかを選んで解答する。

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

問題2(7点満点):これまで作成してきたプログラムのうち一番頑張ったものをWebページに掲載する。文法の良し悪しで採点する。

なお、どちらの問題を解いた場合もレポートの末尾に、1月より実施する自由製作課題のメンバーを記載すること。自由製作課題は5〜6名のグループで協力してプログラムを作成するというものである。記載がない場合および記載したメンバー数が少ない場合は、こちらで戦力が均衡するように配分する。提出期限後の申し出は受け付けられない可能性が高いので注意すること。自由製作課題の詳細は次回のページを確認すること


  • 提出先:naoya@e.koeki-u.ac.jp
  • 提出期限:12/24(日)23:59
  • メールのSubject:自分の学籍番号-kadai08
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降は下記の構成とする

問題1の場合

  1. データを入力するWebページのURL
  2. 作成したプログラム(CGIスクリプト)
  3. プログラムの説明
  4. 感想
  5. 自由製作課題のメンバー(5人まで)

問題2の場合

  1. プログラムを掲載したWebページのURL
  2. 感想
  3. 自由製作課題のメンバー(5人まで)

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

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

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

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