logo

บทเรียน ONLINE : การเขียนภาษา PERL
[ การทำชุดทดสอบ online แบบสุ่ม ]
ดูชุดใช้งานจริงที่ Quiz online หรือทดสอบโปรแกรม ข้อสอบ online ชุดบทเรียน นี้ที่ quizsam.pl

  1. ข้อควรทราบ
  2. โปรแกรม เรียกข้อสอบให้ทำ และตรวจคำตอบ
  3. แบบฝึกหัด
ข้อควรทราบ
  1. ตามที่มีผู้สนใจขอ ให้เปิดเผย source code ของชุดทดสอบ online บัดนี้ ก็ได้โอกาสอันควรที่ผมจะทำบทเรียนชุดนี้แล้ว ซึ่งบทเรียนชุดนี้จะประกอบด้วยแฟ้ม 2 แฟ้ม เท่านั้นคือ quizsam.pl เป็นโปรแกรมเลือกข้อสอบมาให้ทำ และทำการตรวจข้อสอบในตัว และ quizsam.qiz เป็นแฟ้มข้อสอบ ซึ่งผู้ออกข้อสอบต้องสร้างขึ้นมาใช้เอง
  2. ข้อสอบในแฟ้ม quizsam.qiz นั้น มีรูปแบบตามข้างล่างนี้ หรือ click here
    t0001:ชื่อเดิมของประเทศไทยคือ อะไร:สยาม:สุโยทัย:อยุธยา:กรุงเทพฯ:1
    t0002:2+3 เท่ากับเท่าไร:3:2:9:5:2
    
    ซึ่งข้อมูลจะแยกกันด้วย : และประกอบด้วย 7 เขตข้อมูล คือ
    รหัสข้อสอบ:คำถาม:ตัวเลือก1:ตัวเลือก2:ตัวเลือก3:ตัวเลือก4:เฉลย
  3. ท้ายนี้ ผมว่าโปรแกรมนี้ไม่ยาก เพราะแบ่ง subroutine ไว้ชัดเจน และโปรแกรมก็ไม่ได้ยาวอะไร ลองดูนะครับ

โปรแกรม เรียกข้อสอบให้ทำ และตรวจคำตอบ
คำอธิบายโปรแกรม นิดหน่อย
• ตัวแปร mainquiz ได้จากการเช็คค่าว่า รับผ่าน query_string หรือ STDIN
• นำตัวแปร mainquiz ไปเลือกที่จะทำเป็นชุดข้อสอบ ให้ทำ หรือชุดเฉลยจากที่ได้ทำแล้ว
Source code ของ quizsam.pl
#!/usr/local/bin/perl
# This is how to call quiz http://www.thaiall.com/quiz/quizsam.pl?thai&5
$basedir = join '',$ENV{DOCUMENT_ROOT},"/quiz/";
&checkgetsys;
&header;	
if ($mainquiz eq "question") { &getquestion; } else  { &checkanswer; }
print'<hr><center>bye bye bye bye</body></html>';
# ===== end of main =====
sub checkgetsys {
$getsys = $ENV{"QUERY_STRING"};
$getsys =~ tr/+/ /;
$getsys =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$getsys =~ s/~!/~!/g;
$_ = $getsys;
$x = tr/#-@A-Za-zก-ฮฯ-๙/ /cs;
$getsysurl = $_;
$mainquiz = "question";
@gs = split /&/, $getsysurl;
$subj = $gs[0];  # สำรองไว้ให้เขียนโปรแกรมเดียว แต่ใช้กับข้อสอบได้หลายชุด
$amt = $gs[1]; # จำนวนข้อสอบที่ต้องการทำ
$idquiz = $^T;
$title = "ทดสอบความรู้รอบตัว ชุดประเทศไทย";
if ($subj ne "thai") { $subj = "thai"; }
if ($amt ne "3" and $amt ne "5") { $amt = "5"; }
$fname = "quizsam.qiz";
# check answer input
$getsys = <STDIN>;
$getsys =~ tr/+/ /;
$getsys =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$getsys =~ s/~!/~!/g;
$_ = $getsys;
$x = tr/#-@A-Za-zก-ฮฯ-๙/ /cs;
$getsysform = $_;
if (length($getsysform) > 5) {
	$mainquiz = "answer";
	@gs = split /&/, $getsysform;
	foreach $pair (@gs) {
		  ($name, $value) = split(/=/, $pair);
		  $FORM{$name} = $value;
		  if (length($name)>4) {  push @idnum, $name; }
	}
	$subj = $FORM{'subj'};	
	$amt = $FORM{'amt'};	
}
}
sub header	{
print"Content-type:text/html\n\n";
print'<html><head><title>ThaiAll >> ',$title,'</title></head>',"\n";
print'<body bgcolor=#fffffd><font face="microsoft sans serif" size=0><center>';
print'<a href=http://www.thaiall.com/quiz/>Thaiall Quiz Online</a><br>';
print'[<a href=/quiz/quizsam.pl?thai&3>ชุด 3 ข้อ</a> | ';
print'<a href=/quiz/quizsam.pl?thai&5>ชุด 5 ข้อ</a>]</center><hr>';
}
sub getquestion {
print'<center>You open ',$title,' in type ',$amt,' </center><hr>';
open(fn, "<$basedir$fname" );
@bfn = <fn>;
close(fn);
$cntr = @bfn;
$dif = ($idquiz % 5) + 2 ;
for $r (1 .. $amt) {
	$onr = ($idquiz / $r * $dif) % $cntr;	
	push @keepar , $bfn[$onr];			
}
print '<font size=2>';
print '<ul><form method=post action=/quiz/quizsam.pl>';
print '<input name=subj type=hidden value=',$subj,'>';
print '<input name=amt type=hidden value=',$amt,'>';
for $j (0 .. $amt-1) {	
	@recq = split ':',$keepar[$j];
	$num = $recq[0];
	$ques = $recq[1];
	$c1 = $recq[2];
	$c2 = $recq[3];
	$c3 = $recq[4];
	$c4 = $recq[5];
	$ans = substr($recq[6],0,1);
	print $j+1,". <font size=3>",$ques," <font size=0>[",$num,"]</font></font><br>","\n";
	print "<ul>";
	print "<input type=radio name=",$num," value=1>",$c1,"<br>";
	print "<input type=radio name=",$num," value=2>",$c2,"<br>";
	print "<input type=radio name=",$num," value=3>",$c3,"<br>";
	print "<input type=radio name=",$num," value=4>",$c4,"<br>";
	print "<input type=radio name=",$num," value=0 checked>all error<br>";
	print "</ul>";	
}
print '<hr><center><input type=submit name=submit value=Check>';
print '<input type=reset name=reset value=Reset></center>';
print '</form></ul></font>';
}
sub checkanswer {
print'<center>Request to check the answer : ',$title,' in type ',$amt,'</center><hr>';
open(fn, "<$basedir$fname" );
@bfn = <fn>;
close(fn);
$cntr = @bfn;
$isright = 0;
$iswrong = 0;
$isnone = 0;
print "<ul>";
for $j (0 .. @idnum-1) {
	for $k (0 .. $cntr) {
	  ($xnum,$xques,$xc1,$xc2,$xc3,$xc4,$xans) = split(/:/,$bfn[$k]);
	  $xans = substr($xans,0,1);
	  if ($idnum[$j] eq $xnum) {
		print $j+1,". <font size=3>",$xques," <font size=0>[",$xnum,"]</font></font><br>","\n";	
	  	print "<font size=2><ol>";		
		if ($xans eq "1") { print "<li><b>",$xc1,"</b>";} else {print "<li>",$xc1;}
		if ($xans eq "2") { print "<li><b>",$xc2,"</b>";} else {print "<li>",$xc2;}
		if ($xans eq "3") { print "<li><b>",$xc3,"</b>";} else {print "<li>",$xc3;}
		if ($xans eq "4") { print "<li><b>",$xc4,"</b>";} else {print "<li>",$xc4;}				
		print "<br>";
		if ($FORM{$xnum} ne "0") {
			if ($FORM{$xnum} eq $xans) {
				print "<font color=#ff0000 size=0>Right";
				$isright++;				
			} else {
				print "<font color=#0000ff size=0>";
				print "<b>",$FORM{$xnum}," wrong but ",$xans," right</b>";
				$iswrong++;
			}			
		} else {
			print "<font color=#aaaaaa size=0><b>not decision</b>";
			$isnone++;
		}
		print "</font><hr></ol></font>";
	  }
	}
}
print '<hr></ul>';
$workit = $isright + $iswrong;
print'<font size=3>All ',$workit,'<br>Right ',$isright,'<br>Wrong ',$iswrong;
print'<br>None ',$isnone,'<br>';
}

แบบฝึกหัด
    ให้ทำตามโจทย์ต่อไปนี้
  1. ทำชุดข้อสอบตามนี้เลยครับ หมายถึง copy ไปและปรับปรุงให้ใช้ได้
  2. เปลี่ยนข้อสอบ และรูปแบบการแสดงผล
  3. เพิ่มชุดข้อสอบ โดยใช้โปรแกรมเดียว แต่เรียกข้อสอบได้หลายชุด
  4. บทเรียนนี้ เรียกข้อสอบแบบสุ่ม แต่ซ้ำได้ ให้ท่านทำแบบไม่ซ้ำ