職案人

求職・歴史・仏教などについて掲載するつもりだが、自分の思いつきが多いブログだよ。適当に付き合って下さい。

シンプルなアンケートを作る

2018年03月17日 | perl
Perlでシンプルなアンケート作る

【環境条件】
Eclipse 4.4(ルナ)
XAMPP 1.8.3 
Perlは既にインストール済み
CGIを使用する時は、必ずApachを起動する

【アンケート】
仕様
1.質問「犬と猫のどちらが好き?」に対して、相手に回答してもらう。
2.回答は「犬」、「猫」、「どちらも嫌い」 の何れかをチェックする形式。
3.各項目の集結が出来るようにする。

画面操作
1.初期画面

2.選択し、「回答」ボタンを押す

3.回答画面
「戻る」ボタンを押して、初期画面に戻る

4.初期画面から、「集計の表示」ボタンを押す

5.アンケート集計が表示される


【アンケートスクリプト】
1)アンケートの質問を表示する画面「enquete-1.html」

ⅰ.最初のフォーム<form action="enquete-2.cgi" method="post">~</form>は、質問に対する回答データを「enquete-2.cgi」に対して送り出すフォーム

ii.このフォームには3つのラジオボタンがあり、16行目の「回答する」と表示された submitボタンを押すと、「犬」を選んだときは ans=0 というデータがpostで送信される。

iii.リスト<ul><li type="disc"><li> ~ </li><ul>は、先頭に「・」を付け、チェックボタンとデータを縦に並べる。

ⅳ.<form action="enquete-3.cgi" >~</form>は「集計の表示」 ボタンと、その処理を委ねるスクリプトを指し示している。

2)回答画面「enquete-2.cgi」

ⅰ.「$datafile = 'enquete.dat';」はデータを入れるファイルの指定。
「@ans =('犬', '猫', 'どちらも嫌い'); は質問項目を要素の初期化。

ⅱ.$in{$key} = $valの解説
#---- フォームデータ取得 ----
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
 ・・・・・・
}else{
 ・・・・・・・
}
以上までは前回説明済み
foreach (split(/&/, $buf)) {
・・・・
$in{$key} = $val;→ハッシュの生成
}
例えば、「犬」 が選ばれ「 ans=0 」というデータが送られてきた場合、ハッシュ %in にキーを ans、その値 $in{'ans'} を0とする要素が設定される。

ⅲ.exists 関数
#---- 回答の計数 ----
if (exists $in{'ans'}) {
  ・・・・
}else{
$msg = "どれかを選んでからお答えください";
}
exists 関数でハッシュ値$in{'ans'}の有無を調べる。→なぜなら、アンケートの質問画面でどの項目も選ばないと、ans データ無しでこのCGI が起動しないからである。そして、選択されて無い時は、"どれかを選んでからお答えください"の表示を出す。

ⅳ.ファイルテスト演算子 -e
if (-e $datafile) {

・・・・・・・・
}

ファイルテスト演算子 -e を使って $datafile が存在するかどうかを調べています。$datafile が存在すれば、このファイルの内容を読み取む。

ⅴ.open関数
if (-e $datafile) {
pen(IN, $datafile);
・・・・
}
標準ファイルハンドル以外を使う場合には、open関数を使用します。そして、open関数を使って、読み込みモードでファイルを開かせる。
構文
→open(ファイルハンドル名, "ファイル名")


ⅵ.ファイル読み込みwhile文
ファイルからテキストデータを読み込む時、while (<IN>) を使うのが便利である。また、while (<IN>)は while(defined($_ = <TXT>)) と同じで、$_ にファイルハンドル<IN> から1行読み込んだ値がセットされる。行入力演算子<>はファイルの終端に来ると、未定義を返す。

while (<IN>) {
chomp;→改行文字だけを削除する。
push(@n, $_);→$_に入ってるファイルデータを配列(@n)に入れる
}
  #クローズ
  close(IN);
}else{ @n = (0, 0, 0); $new=1; }→ファイルが無い時、配列@nに0を入れる

ⅶ.データ
$i = $in{'ans'};#変数←値
$n[$i]++;
回答された ans の値 $in{'ans'} を $i に代入し、データの配列 @n の $i 番目の要素 $n[$i] をインクレメント(1を加算)する

ⅷ.ファイルへの書き出し
open(OUT, ">$datafile");
→「enquete.dat」ファイルを出力モードでオープンする。
foreach (@n){print OUT "$_\n";}
→更新された配列 @n のデータが変数$_に入り、ファイルハンドルOUTが示す$datafileに書き出す。
close(OUT);→ファイルを閉じる

■オープンモード


ⅸ.ファイルのパーミッション変更
if ($new) { chmod(0666, $datafile); }
→この書き出しで新規にファイルが作られたときは、パーミッションですべてのユーザーにファイルの書込権限を与えている。

$msg = "あなたは 「$ans[$i]」 の$n[$i]人目です";
→例えば、 "あなたは 「犬」 の5番目です" というようなメッセージを設定している。
} else {
$msg = "どれかを選んでからお答えください";
}

Ⅹ.結果表示
#---- 回答の表示 ----
print <

ご回答の表\示


$msg


<form action="enquete-1.html"> ←フォームを使って入力画面に戻る
<input type="submit" value=" 戻る ">
</form>\n</body>\n</html>
END


3)アンケート集計画面「enquete-3.cgi 」

#!/usr/local/bin/perl

$datafile = 'enquete.dat';←データファイル名の設定
@ans = ('犬', '猫', 'どちらも嫌い');←質問項目を要素とする配列の設定

#---- データ読み取り ----
if (-e $datafile) {
open(IN, $datafile);
while (<IN>) {
chomp;
push(@n, $_);
}
close(IN);
} else { @n = (0, 0, 0); }
ここまでは、回答画面の処理と同じで、$datafileを読み取る処理をしている。
#---- 集計の表示 ----
print <

集計結果



    END
    $i = 0;
    foreach (@ans) { print "
  • $_ : $n[$i++]\n"; } ←リストの項目を出力しています。
    print <

<form action="enquete-1.html">
<input type="submit" value=" 戻る ">
</form>\n</body>\n</html>
END

以上




コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

フォームデータの表示/perl

2018年03月08日 | perl
フォームデータの表示/perl

【環境条件】
Eclipse 4.4(ルナ)
XAMPP 1.8.3 
Perlは既にインストール済み
CGIを使用する時は、必ずApachを起動する
参照サイト→フォームデータの表示

■フォームデータの表示(ブラウザ⇄サーバー)
・入力フォーム「form.html 」


・データ送信「form.cgi」して得られた結果


■スクリプト
1)フォーム「form.html 」


2)フォームデータ「form.cgi」


【解説】
・フォームの作り方
フォームはブラウザ側から Webサーバーにデータを送り出すためのもので、 <form ・・・ >~</form>の様にform タグを使って表す。
form タグには action 属性が必須です。
action 属性→起動するCGIファイルの URL を相対アドレスで指定します
method属性→送信するときの転送方法を指定する(getか、postか)

・コントロールの配置
form 要素の中に、テキストボックスやボタンなどいろいろなコントロールと呼ばれるものを配置する出来る。
<form>
データ1: <input type="text" name="data1"><br>
データ2: <input type="text" name="data2"><br>
好みの色:
<input type="radio" name="iro" value="red" checked> 赤
<input type="radio" name="iro" value="blue"> 青
<p><input type="submit" value="送信する"></p>
</form>

・入力コントロール<input>
1)<input type="text" name="data1">のtype属性には下図の通りある。ここではテキストボックスを使用する為、「text」を指定し、name 属性でテキストボックスの名前「data1」を付ける。


2)<input type="radio" name="iro" value="red" checked>
→value属性は送信される値を指定し、checkedは初期値で選択された状態にする

・フォームデータ「form.cgi」の解説
送信データ(入力フォーム→Webサーバ→フォームデータ)
form.html の画面から
データ1: 「ABC DEF」
データ2: 「日本」
好みの色: 「赤」
と入力したとすると、

送信されるデータは「data1=ABC+DEF&data2=%93%FA%96%7B&iro=red」となる。
但し、「&」は区切り文字、「+」は空白を示す
参考サイト→データ入力

#---- データ取得 ----
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
} else {
$buf = $ENV{'QUERY_STRING'};
}
意味
→若し、環境変数 'REQUEST_METHOD' の値が 'POST' なら {
環境変数 'CONTENT_LENGTH' にセットされたデータの長さの文字列を、標準入力STDIN から変数 $buf に読込め。
} 環境変数 'REQUEST_METHOD' の値が 'POST' 以外なら {
環境変数 'QUERY_STRING' にセットされた文字列を、変数 $buf に代入せよ。
}
・ post の場合のSTDINとは画面からの入力の事で、Webサーバーは、ファイルハンドル STDIN を使ってフォームから入力されたデータをread 関数で読み取ることができるようにする。
変数$bufには、「data1=ABC+DEF&data2=%93%FA%96%7B&iro=red」が読み込まれる。

・文字列を分割する
つまり、data1=ABC+DEF&data2=%93%FA%96%7B&iro=redを&で分割する
@data = split(/&/, $buf);
foreach (@data) {
($key, $val) = split(/=/);
$val =~ tr/+/ /;
$val =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$in{$key} = $val;
}
@data = split(/&/, $buf);
→ split 関数の第1引数/&/ は 「デリミタ」 と呼ばれるもので、$bufのデータを「&」で分割する。よって、配列 @data に、次のようにデータが格納される。
$data[0] = "data1=ABC+DEF"
$data[1] = "data2=%93%FA%96%7B"
$data[2] = " iro=red"

・ foreach ループ
foreach (@data){}が実行する都度、配列 @data の各要素が $_ に代入され、次のスクリプト($key, $val) = split(/=/);で、 $_ に代入された文字列を 「= 」 という 「区切り文字」 の前後に分割して、$key と $val に代入しています。

なお、split(/=/)→第2引数を省略した場合には、Perlのグローバル変数$_ が用いられる。

・変換演算子tr///
$val =~ tr/+/ /; →$val に代入されている文字列の中に、「+ 」 という文字があれば、これをスペースに変換する命令。例えば、ブラウザから "ABC+DEF" という文字列を送られたら、"ABC DEF" に変換するというもの。書式→$x =~ tr/変換対象の文字リスト/変換する文字リスト/;

・正規表現とは
ある特定の文字列ではなく、文字列の一部をパターン化して表現する手法をいいます。Perlでは、パターンマッチ演算子として、スラッシュ ( /パターン/ ) で囲んだ文字列が正規表現であるとされ、性格上、正規表現は条件式と併用して用いられることが多い。→パターンマッチ演算子

・置換演算子 s///
書式(s/パターン/置換文字列/修飾子)で、修飾子は特別な置換方法を指定する場合にのみ使用する。
$val =~s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
→/%([0-9a-fA-F][0-9a-fA-F])/ の部分はマッチ演算子で、%を取り除いた英数字と照合させ、一致した値を変数$1に入る。

→/chr(hex($1))/ は$1 に代入された文字列を加工している。 hex 関数は渡された引数を16進数の文字列と認識して10進数に変換する関数。chr関数は引数として渡された文字コードに対応した文字を返す関数。

→/eg;に関して説明すると、修飾子eは置換文字列として書いてある部分、この場合の chr(hex($1)) を、文字列としてではなく関数や式として評価することを指示。
修飾子g は、1つだけではなくマッチしたすべてを置換するという指定。

・フォームデータの整理、出力
→$in{$key} = $val;はフォームデータからハッシュ %in (連想配列)を生成する為の命令。
即ち、この foreach ループは3回まわりますが、その都度 'data1' というキーに対して 'ADC DEF' というような値を持つハッシュ、'data2' というキーに対して '日本' というような値を持つハッシュ、 'iro' というキーに対して 'red' というような値を持つハッシュが生成される。

→foreach (sort keys %in) {print qq($_: $in{$_}\n);} は、このハッシュ %in の内容を出力するための処理。
keys %in はハッシュ%in のキーだけを取り出した配列。(sort keys %in)はsort関数を使って配列キーをソートしている。従って、ここの処理は1回まわる度に、ソートされたキーの配列から1つずつキーが取り出され、それを $_ に代入し、{print qq($_: $in{$_}\n);} で キー:値を出力している。
なお、qq()は ダブルクォート演算子





コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

perlの環境変数について

2018年03月04日 | perl
perlの環境変数について


【環境条件】
Eclipse 4.4(ルナ)
XAMPP 1.8.3 
Perlは既にインストール済み
CGIを使用する時は、必ずApachを起動する

【環境変数について】
■WEB画面


■CGIスクリプト


・・・解説・・・

1)ハッシュ(連想配列)
・配列が「添え字」という番号で要素を指定するのに対し→ハッシュは 「キー」 という文字列で要素の 「値」 を指定する。その為、ハッシュでは、要素の順番を気にする必要が無い。

・%ハッシュの初期化
%data = ("name", "山田", "tel", "123-4567", "sex", "男");の様に記述する。なお、(キー1、値1、キー2、値2、キー3、値3)の順番に成ってる。

・keys 関数
ハッシュからキーだけを取り出した配列を作る時、@keylist = keys %data;

・values 関数
ハッシュから値だけを取り出した配列を作る時、@valuelist = values %data;

・each 関数
ハッシュからキー、値を取り出す時、($key, $value) = each %data;

2)環境変数用の%ENV
Perlの%ENV ハッシュは、環境変数の読み出し、書き替え、追加設定などを行う事に使用する。
@keylist = keys %ENV;は%ENV からキーだけを取り出し、配列@keylistに代入している。

3)sort 関数
書式
ソートされたリスト = sort [ソート順の定義] ソート対象リスト
@sorted = sort @keylist;は環境変数を文字コード順にソートし、配列@sortedに代入している

4)foreach ループ
書式
foreach 変数 (配列) {
・・・
}
・foreach ループでは、ループが回る度に、配列 @sorted の要素が順に $_ に代入する処理をしている。

$val = $ENV{$_} || " "→このキー $_ に対応する値 $ENV{$_} を $val に代入しています。若し、値 $ENV{$_} が 「空の文字列」 の場合には、$val には " " が代入される。  は、HTMLのソースで使われる半角スペース文字を表す記号。

この処理は、HTML のテーブルに空のセルがあると、その枠線が表示されないため、セルに書き込む文字列が空の文字列の場合には   を書いて、枠線が必ず表示されるためのもの

5)print qq( )
qq( ) というのは、ダブルクォートの別の書き方。つまり、「qq( ・・・) 」 と 「" ・・・" 」 は同じで、ヒアドキュメントの場合に、よく使われる。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

CGIのif・forの例文

2018年02月28日 | perl
CGIのif・forの例文


【環境条件】
Eclipse 4.4(ルナ)
XAMPP 1.8.3 
Perlは既にインストール済み
CGIを使用する時は、必ずApachを起動する

【CGIスクリプト】
ブラウザ


スクリプト


【解説】
1.rand 関数
$n1 = int(rand 6) + 1;のrand関数は0以上 6未満のランダムな数を返し、int 関数は小数点以下を切り捨てて整数を返す関数

2.繰り返し処理 (for ループ)
for ループ文の書式
for ( ループに入る時の初期設定; ループ継続条件; ループ1回毎の処理 ) { 処理; }

for ($s1 = '', $i = 0; $i < 4; $i++) はループに入る時の初期設定 として、「$s1 = '', $i = 0 」 と設定している。
「$i < 4 」はループ継続条件 で、これを満たしている間は、{$s1 = $s1 . '●'; }の処理を実行する。{ $s1 = $s1 . '●'; }の「.」は文字列結合演算子で、$s1と●を結合している。
この処理を終了後、$i++を実行し、$iが4以上に成ったら終了

3.条件分岐 (if 文)
if ($n1==4) { $msg .= '散歩中に犬に襲われる危険あり。注意しましょう。'; }
elsif ($n1==1 or $n1==6) {$msg .= '今日はきっと幸運に恵まれます。'; }
else { $msg .= '運気上昇の兆しあり。頑張りましょう。'; }

$n1==4なら、$msgに「散歩中に犬に襲われる危険あり。注意しましょう。」
$n1==1 or $n1==6なら、$msgに「今日はきっと幸運に恵まれます。」を代入
それ以外なら、$msgに「運気上昇の兆しあり。頑張りましょう。」を代入
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

時刻で変化する画面--CGI

2018年02月24日 | perl
時刻で変化する画面--CGI

【環境条件】
Eclipse 4.4(ルナ)
XAMPP 1.8.3 
Perlは既にインストール済み
CGIを使用する時は、必ずApachを起動する

【時刻で変化する画面】
■ブラウザ画面



□CGI スクリプト「time.cgi 」


【解説】
1)配列の宣言と初期化
my @msg = ('ぐーぐー', 'おはよう', 'こんにちは', 'こんばんは');←宣言と初期化をしている。
@msg は 配列を示す。更に、@msg 配列の4要素は$msg[0]、$msg[1]、$msg[2]、$msg[3] として表せられる。よって
$msg[$n1]の$n1 が 1 であれば、 $msg[1] は 'おはよう' ですから、「おはよう」が表示される。

2)時間処理の関数
配列をリスト形式で受け取る
($sec, $min, $hour, $day, $mon, $year, $wkday) = localtime(time);
localtime()はtime関数形式の時間をローカル時間に変換している

「月」 は 0~11 の数字で表されており、「曜日」 は 0~6 の数字で表されていることです。日本では、1月、2月、・・・ また 日曜、月曜、・・・ といいますが、英語圏では、Jan, Feb, ・・・ また Sun, Mon, ・・・ というように呼び方が異なるため、ユーザー側で任意に処理できるように数字で返しているのです。日本では 「月」 を数字で表しているので、 $mon++; でインクレメント演算するだけで済みます。「曜日」 を表すのはすこし厄介で、配列 @youbi を定義して、$wkday が 0 であれば$youbi[$wkday] で '日' を表すようにしています

「年」 は、1900 を足したときに西暦となる数字が返されます。そのため、11行目で $year += 1900; の演算を行っています。

3) int 関数
$n1 = int($hour/6); について
$hour は、現在の時間を表す 0~23 の何れかの値です。この $hour を 6 で割る演算を $hour/6 で行い、その演算結果を int 関数に引数として渡す。 int 関数は、与えられた引数の小数点以下を切り捨てて整数を返し、値は変数$n1 に代入される。

4)ヒアドキュメント
print <
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする