ラウンジ(兼FAQ掲示板)

あんQについて質問です。
過去ログ NO.1165064288
□ ひろたか [2006年12月01日17時36分]
NXerさんたびたびの質問について、いつもご回答いただきましてありがとうございます。
先日も書かさして頂きましたアンケートの次のアンケートページの事ですが、>ボタンにて10アンケートテーマごとにどんどんページ送りできるようにできないでしょうか?
もちろん<はページが戻るようにも
私なりに調べて心みてみるもすべて上手くいかず困りはてています。
教えて頂ければ有難いです。
あと、if ($open_mode)から始まるものをボタンにするには
print "<form action='$script?mode=new_open' method=POST>\n";
print"<input type='submit' value='新しいメッセージをつくる’>\n";
こんな事ではないのでしょうか?
あわせて教えてください
□ NXer [2006年12月02日13時31分]

>どんどんページ送りできるようにできないでしょうか?

質問、疑問に答えが内在する、という常識(conventional wisdom)
はコンピュータ・サイエンス(computer science)にもあてはまりそう
です。当方が学んだその教科書例題も上のようなものです。NXerです。

その1)アルゴリズム 考え方-----------------------------------

引用文は日常語ですが、すこしづつ変形してperlというスクリプト言語
で表現できるようにしてみます。また、添え字のいろいろな変化を列挙
します。自由に付け足して、スクリプト化してください。

1 (単位ページごとに)(どん)(どん)、、、
2  (1〜10ページごとに)(どん1)(どん2)、、、、
 2.1 単位ページ 1〜5、1〜10、1〜20など
 2.2 ボタンを押す、マウスをクリックする回数(どん)の添え字1,2,3、、i
3.1 添え字は、1づつ加算する、つまり1の後に2、その次3、、、i
3.2 添え字は、仮に今5とすると4、3、、、1と戻る。
3.3 最大値よりも上は、1に戻る、最小値より下は1を最下限とする
3.4 添え字1〜iの任意の数から、最初に戻る。つまり81〜90を
   見ていても、1〜10に速攻で戻る。
-----このように、日常よくつかう、どんどんなど擬態語の日本語も大変論理的
です。曖昧さの介在する余地がありません。専門用語をむりに使う必要はない
ようです。----

その2)(どん1)(どん2)(どん3)(どん4)などの添え字の処理方法

2.1 スクリプトに添え字(引数)を書き込む処理例

過去ログで提案した例は、およそ30件*3画面(90件程度)の
表示も可能と考えて、10数件を3画面でテストしたものです。
添え字を下のような$page_view変数で処理した例です。

if (($page_view<0 && $count<=5)||($first_view>=1 && $count<=5)){&subject_view;}
elsif ($page_view1>=1 && ($count>=6 && $count<=10)) {&subject_view;}
elsif ($page_view2>=1 && $count>10) {&subject_view;}

この処理のよい点:スクリプトで対応できるため、変更が簡単です
欠点:ひろたかさんの要望のように小単位多テーマ処理では、場合分け
が10件*10=100件などの場合のように多くなり、スクリプトが煩雑になり
ます。

2.2 スクリプトに添え字を書き、それを表示単位の倍数とする
#-----------------------------------------
if ($count > 10*$vcount && $count<=10*($vcount+1)){&subject_view;}
}
#---------------------------------------------
print "</table>\n</blockquote>\n";
---------------------------------------
この場合のよい点は、あらかじめアンケートテーマの順位を
個別に知っている場合です。
例 1〜10のページ、11〜20のページ、、、、91〜100のページ
ボタンを作成して、その値をmode=1,, として1の時$vcount=1 と
代入処理をするものです。51〜60ページの後、一回のクリックで
21〜30ページに飛ぶことができます。押し込み式で進む、戻る
ボタンの戻るを選び、さらに、それを2度押し込むマウス操作
が必要になります。高齢者や児童などに画像アンケートをして
いただくには、押し込み型処理よりも優れている気がします。
スクリプトも複雑ではありません。画像ボタンにすれば、もっと
分かりやすくなります。

2.3 添え字をデータとしてディスクに保存して利用する

perlでは、メモリーに直接添え字の値を書き込み利用すること
ができません。そこで外部記憶装置のデータファイルを使います。ハード
に依存しないことから汎用性があります。

>私なりに調べて試みてもすべて上手くいかず困りはてています。

cgiの設置運用では考える必要のないことですが、ウェブプログラミン
グでは、ファイルの書き込み(IN, READ)や読み出し(OUT,WRITE)処理
をする必要があります。
変数の値はスクリプトの実行で常に初期値ゼロやヌルストリングから始
まります。見かけ上では、どんどん押し込むだけのことですが、どんど
んの添え字は、その都度増減します。その都度添え字の値を保存して管
理する必要があります。

以下は、そのためのサブルーチンの追加作業です。参考サイトとして
杜甫々さんをご覧ください。

2.3.1 スクリプト初期値設定

---------------------------------行番号は当方の編集済み番号
49 #view_count 表示カウント変数
$vcount=0;
#---------------- 初期設定ここまで ----------------#

2.3.2 添え字増減、リセットの分岐文
-----------------------------------------
124 &get_cookie;
-------------------2行挿入
if ($in{'mode'} eq 'forward' || $in{'mode'} eq 'back') {&view_count;}# 1増減
if ($in{'mode'} eq 'end') {&view_initial;}# $vcountリセット
------------------------
if ($in{'mode'} eq 'reg' || $in{'mode'} eq 'adreg' || $in{'mode'} eq 'change') { ®ist;
------------------------------

2.3.3 表示ルーチン1、進む戻る ガイド

-------------------
181 else { $inf = "終了";}
}
#-----------------------------------------表示単位 10ヶ単位 
if ($count > 10*$vcount && $count<=10*($vcount+1)){&subject_view;}
}
#---------------------------------------------進む、戻る、始めに戻る
print "</table>\n</blockquote>\n";
if ($open_mode) { print "■<a href='$script?mode=forward'> 進む </a><br>\n"; }
if ($open_mode) { print "■<a href='$script?mode=back'> 戻る </a><br>\n"; }
if ($open_mode) { print "■<a href='$script?mode=end'> 始めに戻す </a><br>\n";}
---------------------------------------------------
if ($open_mode) { print "■<a href='$script?mode=new_open'>新しいアンケートテーマを設定する</a>\n";
print "<br>\n";}
print "</blockquote>\n";

2.3.4 表示ルーチン2、添え字読み出し、書き込み、初期化ルーチン

----------------------------過去ログと同じルーチン あんQの最下段に追加
965 sub subject_view{
print "<tr><td align=center>$count</td><td><a href='$script?data=$_'>$subject</a></td><td>$up</td><td>$inf</td></tr>\n";
}
-------------------表示添え字読み出しと増減処理など、そして書き込み
965 sub view_count{
open(READ,"count.dat") || &error("[ $tmp$file ]が開けませんでした。");
while (<READ>){
$vcount = $_;
}
close(READ);
if ($in{'mode'} eq 'forward'){
$vcount++;}# $url 加算 view が一度押されるたびに1増加
elsif ($in{'mode'} eq 'back') {$vcount--;}
if ($vcount<0){$vcount=0;}#下限は0
if (($vcount*10-$count)>=31){$vcount=0;}#上限は初期化する
open(WRITE,"> count.dat") || &error("[ $tmp$file ]が開けませんでした。");
print WRITE $vcount;
close(WRITE);
}
-----------------------------データリセット 
980 sub view_initial {#初期化、進む戻るを途中で止めた時始めに戻す
$vcount=0;
open(WRITE,"> count.dat") || &error("[ $tmp$file ]が開けませんでした。");
print WRITE $vcount;
close(WRITE);
}
-----------------------------ここまで新規追加

その3)スクリプト説明と運用愚案
--------------------------- 
while (<READ>){
$vcount = $_;
}
close(READ);
---------------------------
ファイルハンドルREADは、すえぽんさんの書式に従いました。<IN>など
自由に設定可能です。$_ は読み込んだ値です。
進むで$vcount++ 1だけインクレメント、 戻るで $vcount-- 1だけ
ディクレメント。ここで問題は、どんどん押し込むと、増減ともにデー
タが存在しなくなることです。
123456789101112、、、30、31、32 のデータとします。
進むで3度目に31、32だけが表示されます。4度目は41〜50はデータなし。
そのため上限をif (($vcount*10-$count)>=31){$vcount=0;}#上限は初期化する
としました。当方のデータでは、4度目はスクリプトどおり初期化されて
1〜10になりました。より多くのデータでこの式が正しいか検証してください。
データ最大値を$dmaxとし、それを保存して判断する方が確実かもわかりません。

どんどん進めて、例えば添え字6で投票したりすると、次に最初に
戻るには、戻るボタンをどんどんどんどんどんと押します。これは
不経済なのではじめに戻るボタンを作ってみました。利用者がどのような
行動をとるかは予測できないために、リセットボタンで迷わないように
しておきます。

この処理方法のよい点は、進むと戻るの単純な判断で多数のテーマを選択
できることです。しかし、文字フォントが小さい場合、何度も押し込んで
行き過ぎたり戻りすぎたり、分からなくなってまた、初めにもどたりする
ことがあるかも知れません。利用者にやさしいウェブプログラミングは
機能的にエレガントであれば、ほんらい使いやすさに結びつくはずです。

しかし、時にそれがプログラマの自己満足におわることもあります。
運用前に仲間内で試し、内容によっては、ひろたかさんの運用環境は不明
ですが、こどもさんたち、彼ら彼女らの保護者のみなさん、また、勤務
現場、営業現場の方方で試用に協力いただくなどして改善することになる
かもわかりません。

>あと、if ($open_mode)から
前後のスクリプトをお知らせください。すでに長文のスクリプトで双方に
かなりずれがあると思われます。自作例も、エラーメッセージを含めて添
えてください。ラウンジ読者でおなじエラー発生の経験者はおおいとおも
われます。
また、他の未回答のご質問も遠慮なく書き込まれてはいかがですか。興味
のある方から、回答を得ることができるかもしれません。見出しを内容件
名にすると、過去ログになってからもより多くの方に見ていただけます。

☆ 謝辞 ☆
すえぽんさんには、いつも貴重なデジタル空間を愚考愚案で占有して失礼
しています。こころより感謝いたします。
□ ひろたか [2006年12月02日14時36分]
NXerさん回答ありがとうございます。
またまた質問なんですが、現在投票前はグラフが表示されないようになっています。
そして、コメント付きにもなっているのですが、コメントのメッセージ表示部分も投票前には表示しないようにしたいのです。
私なりにこうかなとおもいしてみたのですが、確かに投票前はメッセージ部分が消えているのですが、投票するとメッセージの部分がいくつも出てきてしまう現象になります。
どうすればいいでしょうか?
if ($scoreview>=1){からはじまる行列にprint "</table><br><table cellpadding='15'><tr><td bgcolor='#004080' colspan=40 class=plain><font color='white'>*** この質問・項目へのメッセージ *** <br><br>$mes<br></font></td></tr></table><br>\n";
を移動しただけです。

if ($scoreview>=1){
print "$content</td><td align=right>$point</td>\n";
print "<td><table cellpadding=0 cellspacing=0 class=plain><td class=plain>";
print "<table cellpadding=0 cellspacing=0 bgcolor='$color' class=plain><td class=plain><img src='$grh' width=$len height=10></td></table></td>";
print "<td width=5 class=plain> </td><td class=plain>$perse\%</td></table></td></tr><br>\n";
print "</table><br><table cellpadding='15'><tr><td bgcolor='#004080' colspan=40 class=plain><font color='white'>*** この質問・項目へのメッセージ *** <br><br>$mes<br></font></td></tr></table><br>\n";

}

else {print "$content</td>\n";}#■投票前結果非表示・項目名表示
□ NXer [2006年12月02日17時19分]

どんどん表示で記録ファイルを作成する必要がありますので
追記します。NXerです。

2.3.5 空のデータファイル転送

count.dat というファイル名を
/anq/ ディレクトリ下に転送します。
ファイル作成メモ
********************************
エディタで新しいページを開きそのままcount.dat名
で保存します。空のファイルという警告を無視して保存
します。
********************************
パーミッションは666です。サーバの仕様に
従って読み書きができるように設定します。

>メッセージ表示部分も投票前には(非)表示に
するには、移動ではなくて、新たに旗を新設します。NXerです。

いろんな旗が競合しそうですが、それぞれ一つの機能しかないこと
から新設してみました。

1)初期値設定
----------------------------
49 #得票率表示/非表示フラッグ
$scoreview=0;
#メッセージ入力表示/非表示フラッグ
$mesinput=0;
#---------------- 初期設定ここまで ----------------#

2)サブルーチン分岐文
---------------------------------------------
132 elsif ($in{'mode'} eq 'vote') { $scoreview=1; $mesinput=0;&vote;}
(略)
138 elsif ($in{'data'}) { $scoreview=0;$mesinput=1;&html; }
---------------------------------------
グラフと入力は互いに背反する値ですから、まとめても良いかも
しれませんが、他に使うこともあるかもしれないので追加します。

3)メッセージ表示
--------------------------------
285 # ■ メッセージ表示 ■
286 if ($scoreview>=1){
-------------------------------
print "</table><br><table cellpadding='15'><tr><td bgcolor='gray' colspan=40 class=plain><font color='white'>*** この質問・項目へのメッセージ *** <br><br>$mes</font></td></tr></table><br>\n";
-------------------------------
290 } #286と290の括弧対応、 if ($scoreview>=1){〜}のみ挿入
else {print "</table><br>";}

4)入力フォーム表示
-------------------------------
299 # ■ message用 フォーム■
300 if ($mesinput >=1){
---------------------------------
print "<tr><td colspan=5 class=plain><table class=plain><td class=plain><tr><td>メッセージ (全角$msg_max文字以内で内容、名前(匿名可))<br>\n";
print "<textarea name=mes cols=40 rows=3 wrap=soft></textarea>\n";
------------------------------
304 } #ここまで
--------------------300、304 if ($mesinput >=1){〜 } のみ挿入

おおきなcgiのために、新たな機能を一つ組み込みだけでも数箇所の
変更になります。プログラムにコメントを書き込み保守性の向上を
図ってください。これまでの諸変更をまとめたスクリプトは当方の
手元にはありません。したがって整合性がとれないことがあるかも
わかりません。不具合発生時は、サブルーチンで使っている変数分
析をしてみてください。



suepon.com | CGI作成/CGI制作 | JavaScript | ドメイン検索 | バナー自動作成 | Google ダンスツール | 松浦亜弥 | H.P.memo | パソコン | ネイル

Copyright (C) 2002 - 2008 suepon , All rights reserved. Powered by CGI Script Market.