Annotation of capa/capa51/CapaTools/capautils.1.1.pl, revision 1.1
1.1 ! albertel 1: #!/usr/local/bin/perl -I/usr/local/bin
! 2:
! 3: # <==========================================================================>
! 4: # June 1997 version 1.0 Created by Isaac Tsai
! 5: # Copyright 1997, 1998, 1999
! 6: # September 24 1997 version 1.1 by Guy Albertelli II
! 7: # -put in initialization loop in S_ScanSetDB (need to remove hardlimits)
! 8: # -initialize Max_try in S_Average, before being used
! 9: #
! 10: # <==========================================================================>
! 11: use Cwd;
! 12: require('getopts.pl');
! 13: require('CAPAscreen.pl');
! 14: # =============================================================================
! 15: #
! 16: # =============================================================================
! 17: $Days = int( time / 86400);
! 18: @MonthName = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
! 19: #
! 20: # produces a string "ddMmm19xx" to be used in timestamp or filename
! 21: #
! 22: sub TodayString {
! 23: local($ss, $mm, $hh, $mday, $mth, $yy, $wday, $yday,$isdst);
! 24: local($str);
! 25:
! 26: ($ss, $mm, $hh, $mday, $mth, $yy, $wday, $yday,$isdst) = localtime(time);
! 27: if ($mday > 9) {
! 28: $str = "$mday$MonthName[$mth]19$yy"; # year 2000 problem!!
! 29: } else {
! 30: $str = "0$mday$MonthName[$mth]19$yy"; # year 2000 problem!!
! 31: }
! 32: return $str;
! 33: }
! 34: #
! 35: # produces a string hhmmss-ddMon19xx for timestamps
! 36: #
! 37: sub TimeString {
! 38: local($ss, $mm, $hh, $mday, $mth, $yy, $wday, $yday,$isdst);
! 39: local($str);
! 40:
! 41: ($ss, $mm, $hh, $mday, $mth, $yy, $wday, $yday,$isdst) = localtime(time);
! 42: $ss = "0" . "$ss" if $ss <= 9;
! 43: $mm = "0" . "$mm" if $mm <= 9;
! 44: $hh = "0" . "$hh" if $hh <= 9;
! 45: if ($mday > 9) {
! 46: $str = "$hh$mm$ss-$mday$MonthName[$mth]19$yy"; # year 2000 problem!!
! 47: } else {
! 48: $str = "$hh$mm$ss-0$mday$MonthName[$mth]19$yy"; # year 2000 problem!!
! 49: }
! 50: return $str;
! 51: }
! 52: # =============================================================================
! 53: # Read capa.config into global variables
! 54: #
! 55: sub S_ReadCAPAconfig {
! 56: local($classpath)=@_;
! 57: local($filename);
! 58: local($filename2);
! 59: local($tempfilename);
! 60: local($input_line);
! 61: local($done)=0;
! 62: local($tmp);
! 63:
! 64: @MainPath=();
! 65: push(@MainPath,$classpath);
! 66: $ClassName = substr($classpath,-8,8);
! 67: $filename="$classpath" . "/capa.config";
! 68: $filename2="$classpath" . "/capautils.config";
! 69: foreach $tempfilename ( $filename, $filename2 ) {
! 70: if(-f $tempfilename) {
! 71: open(IN, "<$tempfilename") || die "Cannot open file $tempfilename!";
! 72: LINE: while( ($input_line = <IN>) && (! $done) ) {
! 73: ## skip over comments
! 74: if( $input_line =~ /^\#/ ) { next LINE; }
! 75: chop($input_line);
! 76: # collect _path information and create the corresponding global variable
! 77: if( ($input_line =~ /^(\w+)_path\s*=\s*["]([\.\d\+\-\w\s\/]+)["]$/) ||
! 78: ($input_line =~ /^(\w+)_path\s*=\s*(\S+)$/) ) {
! 79: $tmp = ucfirst lc $1;
! 80: $tmp = "$tmp" . "Path";
! 81: push(@MainPath,$2);
! 82: ${$tmp} = "$2";
! 83: # collect printer_option information
! 84: } elsif ( ($input_line =~ /^\s*printer_option\s*=\s*["]([\.\d\+\-\w\s\/\|\$]+)["]$/) ||
! 85: ($input_line =~ /^\s*printer_option\s*=\s*(\S+)$/ ) ) {
! 86: push(@Printers,$1);
! 87: ##
! 88: # collect _command information
! 89: } elsif ( ($input_line =~ /^\s*(\w+)_command\s*=\s*["]([\.\d\+\-\w\s\/\|\$]+)["]$/) ||
! 90: ($input_line =~ /^\s*(\w+)_command\s*=\s*(\S+)$/ ) ) {
! 91: $tmp = ucfirst lc $1;
! 92: $tmp = "$tmp" . "CMD";
! 93: ${$tmp} = "$2";
! 94: ## print "CMD \$$tmp: [$2]\n";
! 95: ## print "Press RETURN to continue"; $tmp = <>;
! 96: # collect _file information
! 97: } elsif ( ($input_line =~ /^\s*(\w+)_file\s*=\s*["]([\.\d\+\-\w\s\/]+)["]$/) ||
! 98: ($input_line =~ /^\s*(\w+)_file\s*=\s*(\S+)$/ ) ) {
! 99: $tmp = ucfirst lc $1;
! 100: $tmp = "$tmp" . "File";
! 101: ${$tmp} = "$2";
! 102: # var_ definition
! 103: } elsif ( ($input_line =~ /^\s*var_(\w+)\s*:=\s*["]([\.\d\+\-\w\s\/]+)["]$/) ||
! 104: ($input_line =~ /^\s*var_(\w+)\s*:=\s*(\S+)$/ ) ) {
! 105: # we defined a variable name with that value
! 106: $tmp = ucfirst lc $1;
! 107: $Var_name{$tmp} = "$2";
! 108: # two levels of indirection
! 109: # the variable should be ${$2}
! 110:
! 111: # prefix_ definition
! 112: } elsif ( ($input_line =~ /^\s*prefix_(\w+)\s*:=\s*["]([\.\d\+\-\w\s\/]+)["]$/) ||
! 113: ($input_line =~ /^\s*prefix_(\w+)\s*:=\s*(\S+)$/ ) ) {
! 114: $tmp = ucfirst lc $1;
! 115: $Prefix_name{$tmp} = "$2";
! 116:
! 117: # assigning an numerical value to a variable
! 118: } elsif ( ($input_line =~ /^\s*(\w+)\s*=\s*([\.\d]+)/) ) {
! 119: ${$1} = $2;
! 120: # print "Assign \$$1: with $2\n";
! 121: # print "Press RETURN to continue"; $tmp = <>;
! 122: # assigning a variable to another variable
! 123: } elsif ( ($input_line =~ /^\s*(\w+)\s*=\s*([\w]+)/) ) {
! 124: $P_code{$1} = "\$$2";
! 125: ## print "PERL $1: { $P_code{$1} }\n";
! 126: ## print "Press RETURN to continue"; $tmp = <>;
! 127: # perl code
! 128: } elsif ( ($input_line =~ /^\s*(\w+)\s*::/) ) {
! 129: $p_var_name = $1;
! 130: } elsif ( ($input_line =~ /^\s*BEGIN_perl/) ) {
! 131: $P_code{$p_var_name} = &E_CollectPerlCode;
! 132: ## print "PERL $p_var_name: { $P_code{$p_var_name} }\n";
! 133: ## print "Press RETURN to continue"; $tmp = <>;
! 134: } elsif ($input_line =~ /[Bb][Aa][Ss][Ee][\s][Uu][Nn][Ii][Tt]/) {
! 135: $done = 1;
! 136: }
! 137:
! 138: }
! 139: close(IN) || die "Cannot close file $tempfilename!";
! 140: }
! 141: # define some global variables if they are not defined properly in capa.config file
! 142: $homework_scores_limit_set = 99 if $homework_scores_limit_set eq "";
! 143: $exam_scores_limit_set = 99 if $exam_scores_limit_set eq "";
! 144: $quiz_scores_limit_set = 99 if $quiz_scores_limit_set eq "";
! 145: $supp_scores_limit_set = 99 if $supp_scores_limit_set eq "";
! 146: $others_scores_limit_set = 99 if $others_scores_limit_set eq "";
! 147: $display_score_row_limit = 40 if $display_score_row_limit eq "";
! 148: ## print "Press RETURN to continue"; $tmp = <>;
! 149: }
! 150: }
! 151: #
! 152: # Collect perl codes from <IN> until it encountered a
! 153: # END_perl statement
! 154: # Skips over comments (begin with a # mark)
! 155: # It then places all the codes withing a pair of '{' and '}'
! 156: #
! 157: sub E_CollectPerlCode {
! 158: local($input_line);
! 159: local($p_code,$done);
! 160:
! 161: $p_code = "{ \n"; # begining of the code
! 162: $done=0;
! 163: while( ($input_line = <IN>) && (! $done) ) {
! 164: if( $input_line =~ /^END_perl/ ) {
! 165: $done = 1;
! 166: } else {
! 167: if( $input_line !~ /^\#/ ) { # skip over comments
! 168: $p_code = "$p_code" . "$input_line";
! 169: }
! 170: }
! 171: }
! 172: $p_code = "$p_code" . " }\n"; # ending of the code
! 173: return ($p_code);
! 174: }
! 175: #
! 176: # Collects e-mail template code until it encountered
! 177: # a END_template statement in the <IN> file
! 178: # It skips over comments that begin with a # mark
! 179: #
! 180: sub E_CollectTemplateCode {
! 181: local($input_line);
! 182: local($p_code,$done);
! 183:
! 184:
! 185: $done=0;
! 186: while( ($input_line = <IN>) && (! $done) ) {
! 187: if( $input_line =~ /^END_template/ ) {
! 188: $done = 1;
! 189: } else {
! 190: if( $input_line !~ /^\#/ ) { # skip over comments
! 191: $p_code = "$p_code" . "$input_line";
! 192: }
! 193: }
! 194: }
! 195:
! 196: return ($p_code);
! 197: }
! 198:
! 199: #
! 200: # $MailCMD comes from the entry 'mail_command' in capa.config
! 201: #
! 202: sub S_Mailto {
! 203: local($e_address,$e_file)=@_;
! 204: local($m_subject);
! 205: local($cmd);
! 206: local($tmp);
! 207:
! 208: $m_subject = "Current Status on $ClassName";
! 209:
! 210: $cmd = "$MailCMD -s '$m_subject' $e_address < $e_file";
! 211: print "Mail File $e_file To $e_address\n";
! 212: system($cmd);
! 213: # ??? How do we know this command successfully returns?
! 214:
! 215: }
! 216:
! 217: # TODO:: Check the validity of $e_addr
! 218: #
! 219: # INPUT: a string represents the category to mail to
! 220: # it could be "3" or "0" or "1,3,4"
! 221: # "0" means 1,2,3, and 4
! 222: # "1,3,4" means 1,3, and 4
! 223: # anything greater than 4 is not valid in the input
! 224: # therefore category 5 represent those that are
! 225: # falling through the gaps of *_high and *_low
! 226: #
! 227: sub S_MailtoCategory {
! 228: local($cat)=@_;
! 229: local(@all_files);
! 230: local(@a_cat);
! 231: local($i,$j,$a_char);
! 232: local($s_id,$s_name,$s_sec,$e_addr);
! 233: local($orig_filename,$new_filename);
! 234: local($tmp);
! 235:
! 236: opendir(EDIR, "$ClassPath/Mail") || die "cannot opendir $ClassPath/Mail!";
! 237: @all_files = grep !/^\.\.?$/, readdir EDIR;
! 238: closedir EDIR;
! 239:
! 240: if( ( $cat =~ /,/ ) || ( $cat == 0 ) ) {
! 241: if( $cat =~ /,/ ) {
! 242: @a_cat = split(/,/,$cat);
! 243: } else {
! 244: @a_cat = (1,2,3,4);
! 245: }
! 246: for( $i=0;$i<=$#all_files;$i++) {
! 247: for( $j=0;$j<=$#a_cat;$j++) {
! 248: $a_char = $a_cat[$j];
! 249: if( $all_files[$i] =~ /([\w\d]+)\.[\w\d]+\.$a_char$/ ) {
! 250: $s_id = $1;
! 251: ($s_name,$s_sec,$e_addr) = S_Lookup_student_name("$s_id");
! 252: if( $e_addr ne "" ) {
! 253: $orig_filename = "$ClassPath/Mail/$all_files[$i]";
! 254: S_Mailto("$e_addr","$orig_filename");
! 255: print "moving $all_files[$i] to $all_files[$i].done\n";
! 256: # move the completed file to *.done
! 257: system("mv $orig_filename $orig_filename.done");
! 258: }
! 259: }
! 260: }
! 261: }
! 262: } else {
! 263: for( $i=0;$i<=$#all_files;$i++) {
! 264: if( $all_files[$i] =~ /([\w\d]+)\.[\w\d]+\.$cat$/ ) {
! 265: $s_id = $1;
! 266: ($s_name,$s_sec,$e_addr) = S_Lookup_student_name("$s_id");
! 267: print "Addr=$e_addr\n";
! 268: print "Press RETURN to continue"; $tmp = <>;
! 269: if( $e_addr ne "" ) {
! 270: $orig_filename = "$ClassPath/Mail/$all_files[$i]";
! 271: S_Mailto("$e_addr","$orig_filename");
! 272: print "moving $all_files[$i] to $all_files[$i].done\n";
! 273: system("mv $orig_filename $orig_filename.done");
! 274: }
! 275: }
! 276: }
! 277: }
! 278: print "DONE Mail, press RETURN to continue"; $tmp = <>;
! 279:
! 280: }
! 281: #
! 282: # It prompts the user to enter an absolute path to a regular class
! 283: #
! 284: sub S_Enterpath {
! 285: local($set)=@_;
! 286: local($notdone,$path,$cfgfullpath,$cfgutilsfullpath);
! 287: local($cfullpath,$rfullpath,$sfullpath);
! 288:
! 289: $notdone = 1;
! 290: while ($notdone) {
! 291: print "Please enter the CLASS absolute path:\n";
! 292: $path = <>; chomp($path);
! 293: if( $path =~ /\/$/ ) {
! 294: $cfullpath = "$path" . "classl";
! 295: $rfullpath = "$path" . "records";
! 296: $sfullpath = "$path" . "records/set$set.db";
! 297: $cfgfullpath = "$path" . "capa.config";
! 298: $cfgutilsfullpath = "$path" . "capautils.config";
! 299: } else {
! 300: $cfullpath = "$path" . "/classl";
! 301: $rfullpath = "$path" . "/records";
! 302: $sfullpath = "$path" . "/records/set$set.db";
! 303: $cfgfullpath = "$path" . "/capa.config";
! 304: $cfgutilsfullpath = "$path" . "/capautils.config";
! 305: }
! 306: if( -d $path ) {
! 307: if( -d $rfullpath ) {
! 308: if( -f $cfgfullpath ) {
! 309: if( -f $cfgutilsfullpath ) {
! 310: $notdone = 0;
! 311: } else {
! 312: print "File [$cfgutilsfullpath] does not exist!\n";
! 313: }
! 314: } else {
! 315: print "File [$cfgfullpath] does not exist!\n";
! 316: }
! 317: } else {
! 318: print "Directory [$rfullpath] does not exist!\n";
! 319: }
! 320: } else {
! 321: print "Directory [$path] does not exist!\n";
! 322: }
! 323:
! 324: }
! 325: return ($path);
! 326: }
! 327: # ----------------------------------------------------------
! 328: # Global menu items to be selected by user
! 329: #
! 330: @Main_menu=(
! 331: "Change class path",
! 332: "Run capastat",
! 333: "Log analysis on Y, N, S, U, and u",
! 334: "Student course profile",
! 335: "CAPA IDs for one student",
! 336: "All CAPA IDs",
! 337: "Item analysis",
! 338: "Item correlation",
! 339: "Email",
! 340: "Print assignment(s) for a student",
! 341: "View score file",
! 342: "View submissions for a student",
! 343: "Quit");
! 344:
! 345: @Prof_menu=(
! 346: "Student number",
! 347: "Student name",
! 348: "Cancel" );
! 349:
! 350: @Email_menu=(
! 351: "Create score file for all students",
! 352: "Create individual e-mail files from the file in 1.",
! 353: "Preview e-mail file randomly from among the files in 2.",
! 354: "Send e-mail files in 2. to a group of students",
! 355: "Cancel" );
! 356:
! 357: @ScoreSortMsg=(
! 358: "Sort by the order of: ",
! 359: " 1. Grade",
! 360: " 2. Student number",
! 361: " 3. Student name",
! 362: " 4. Section",
! 363: " ",
! 364: "3,2 means 'name' first, 'student number' second",
! 365: "1,4,3 means sort by 'grade', 'section' and 'name'" );
! 366:
! 367:
! 368: @SpecifyCategoryMsg = ("Which category?",
! 369: " enter number(s) between 0 and 4",
! 370: " 1,2,4 : categories 1, 2 and 4",
! 371: " 3 : category 3",
! 372: " 0 : all categories" );
! 373: #
! 374: # Only accepts input of 0, 1, 2, 3, and 4, nothing else.
! 375: #
! 376: sub S_EnterCategory {
! 377: local($cat);
! 378: local($done)=0;
! 379: local(@a_cat,$i);
! 380:
! 381: while(! $done) {
! 382: $cat = C_InputSetNum(4,10,45,"",12,,"CATEGORY:", @SpecifyCategoryMsg);
! 383: if( $cat =~ /,/ ) {
! 384: @a_cat = split(/,/,$cat);
! 385: $done = 1;
! 386: for( $i=0;$i<=$#a_cat;$i++) {
! 387: if( ($a_cat[$i] < 0 || $a_cat[$i] > 4) && ($a_cat[$i] ne "" ) ) {
! 388: $done = 0;
! 389: }
! 390: if( $a_cat[$i] == 0 ) {
! 391: $done = 0;
! 392: }
! 393: }
! 394:
! 395: } else {
! 396: if( $cat>= 0 && $cat <= 4 ) {
! 397: $done = 1;
! 398: }
! 399: }
! 400: }
! 401: return ($cat);
! 402: }
! 403:
! 404: # Only allows input of 1, 2, 3, and 4, nothing more
! 405: sub S_EnterSortKey {
! 406: local($key);
! 407: local($done)=0;
! 408: local(@a_key,$i);
! 409:
! 410: while(! $done) {
! 411: $key = C_InputSetNum(2,5,60,"",12,,"KEY:",@ScoreSortMsg);
! 412: if( $key =~ /,/ ) {
! 413: @a_key = split(/,/,$key);
! 414: $done = 1;
! 415: for( $i=0;$i<=$#a_key;$i++) {
! 416: if( ($a_cat[$i] < 0 || $a_cat[$i] > 4) && ($a_key[$i] ne "" ) ) {
! 417: $done = 0;
! 418: }
! 419: if( $a_key[$i] == 0 ) {
! 420: $done = 0;
! 421: }
! 422: }
! 423:
! 424: } else {
! 425: if( $key> 0 && $key < 5 ) {
! 426: $done = 1;
! 427: }
! 428: }
! 429: }
! 430: return ($key);
! 431: }
! 432:
! 433:
! 434:
! 435:
! 436: @EnterSetMsg = ("Which set?");
! 437: @EnterSetsMsg = ("Which set(s)?",
! 438: " 3,7 : from set 3 to set 7 (both inclusive)",
! 439: " 4 : only set 4" );
! 440:
! 441: sub S_EnterSets {
! 442: local($set);
! 443: local($done)=0;
! 444: local($s_from,$s_to);
! 445:
! 446: while(! $done) {
! 447: $set = C_InputSetNum(4,10,45,"",6,,"SET:", @EnterSetsMsg);
! 448: if( $set =~ /,/ ) {
! 449: ($s_from,$s_to) = split(/,/,$set);
! 450: if( $s_from <= 0 || $s_from >= 100 ) { $s_from = 1; }
! 451: if( $s_to <= 0 || $s_to >= 100 ) { $s_to = 1; }
! 452: if( $s_from > $s_to) {
! 453: $tmp = $s_from; $s_from = $s_to; $s_to = $tmp;
! 454: }
! 455: $done = 1;
! 456: } else {
! 457: if( $set> 0 && $set < 100 ) {
! 458: $s_to = $set;
! 459: $s_from = $s_to;
! 460: $done = 1;
! 461: }
! 462: }
! 463: }
! 464: return ($s_from,$s_to);
! 465: }
! 466:
! 467: sub S_InputSet {
! 468: local($set);
! 469: local($done)=0;
! 470:
! 471: while(! $done) {
! 472: $set = C_InputSetNum(4,10,15,"",2,,"SET:", @EnterSetMsg);
! 473: if( $set =~ /\d+/ && $set > 0 && $set < 100 ) { # check entered set
! 474: $done = 1;
! 475: }
! 476: }
! 477: return ($set);
! 478: }
! 479:
! 480:
! 481: @EnterSSNMsg = ("Enter student number?", " (RETURN to exit)" );
! 482: @EnterSNMsg = ("Enter student name (max 30 chars)?",
! 483: "Last, First (Middle)",
! 484: " (RETURN to exit)" );
! 485:
! 486: sub S_InputStudent {
! 487: local($classpath)=@_;
! 488: local($filename);
! 489: local($select,$tmp_sn,$input_line);
! 490: local($student_id,$student_name);
! 491: local($found,$done,$s_name);
! 492: local($match,@matched_entries,$tmp_line);
! 493:
! 494: $select = C_MultipleChoice(4,10,$DialogWidth,"Select student by:","$DisplayPath",@Prof_menu);
! 495: if($select == 1 ) { # specify student number
! 496: while(! $done) {
! 497: $student_id = C_InputStudentID(4,10,24,"",9,"INPUT:",@EnterSSNMsg);
! 498: if($student_id eq "" ) {
! 499: $done = 1;
! 500: } else {
! 501: $student_id = uc($student_id);
! 502: $filename = $classpath . "/classl";
! 503: open(IN, "<$filename") || die "Cannot open file $filename!";
! 504: $match = 0; @matched_entries = ();
! 505: while(($input_line = <IN>)) {
! 506: chomp($input_line);
! 507: $tmp_sn = substr($input_line,14,9); $tmp_sn = uc($tmp_sn);
! 508: if($tmp_sn =~ /^$student_id/ ) {
! 509: $match++;
! 510: # student name begins at column 24 and has 30 chars max
! 511: $student_name = substr($input_line,24,30);
! 512: $tmp_line = "$tmp_sn " . "$student_name";
! 513: push(@matched_entries,$tmp_line);
! 514: }
! 515: }
! 516: close(IN) || die "Cannot close file $filename!";
! 517: if($match > 1 && $match <= 12) {
! 518: $select = C_MultipleChoice(4,10,$DialogWidth," Matched Student Records ",
! 519: "$DisplayPath",@matched_entries);
! 520: $student_id = substr($matched_entries[$select-1],0,9);
! 521: $student_name = substr($matched_entries[$select-1],10,30);
! 522: $done = 1;
! 523: } elsif ($match == 1) {
! 524: $student_id = substr($matched_entries[0],0,9);
! 525: $student_name = substr($matched_entries[0],10,30);
! 526: $done = 1;
! 527: } elsif ($match > 12) {
! 528: $tmp_line = "There are $match records found.";
! 529: C_Warn(4,10,$DialogWidth,"Too many students matched",$tmp_line);
! 530: } else {
! 531: $tmp_line = "Please re-enter student number.";
! 532: C_Warn(4,10,$DialogWidth,"No student found",$tmp_line);
! 533: }
! 534: }
! 535:
! 536: }
! 537: } elsif ($select == 2) { # specify student name
! 538: while(! $done) {
! 539: $s_name = C_InputStudentID(4,10,40,"Enter student name",30,,"INPUT:", @EnterSNMsg);
! 540: if($s_name eq "" ) {
! 541: $done = 1;
! 542: } else {
! 543: $s_name = uc($s_name);
! 544: $filename = $classpath . "/classl";
! 545: open(IN, "<$filename") || die "Cannot open file $filename!";
! 546: $match = 0; @matched_entries = ();
! 547: while(($input_line = <IN>)) {
! 548: chomp($input_line);
! 549: $tmp_sn = substr($input_line,24,30); $tmp_sn = uc($tmp_sn);
! 550: if( $tmp_sn =~ /^$s_name/ ) {
! 551: $match++;
! 552: $student_id = substr($input_line,14,9); # student number
! 553: $tmp_line = "$student_id " . "$tmp_sn";
! 554: push(@matched_entries,$tmp_line);
! 555: }
! 556: }
! 557: close(IN) || die "Cannot close file $filename!";
! 558: if($match > 1 && $match <= 12) {
! 559: $select = C_MultipleChoice(4,10,$DialogWidth," Matched Student Records ",
! 560: "$DisplayPath",@matched_entries);
! 561: $student_id = substr($matched_entries[$select-1],0,9);
! 562: $student_name = substr($matched_entries[$select-1],10,30);
! 563: $done = 1;
! 564: } elsif ($match == 1) {
! 565: $student_id = substr($matched_entries[0],0,9);
! 566: $student_name = substr($matched_entries[0],10,30);
! 567: $done = 1;
! 568: } elsif ($match > 12) {
! 569: $tmp_line = "There are $match records found.";
! 570: C_Warn(4,10,$DialogWidth,"Too many students matched",$tmp_line);
! 571: } else {
! 572: $tmp_line = "Please re-enter student name.";
! 573: C_Warn(4,10,$DialogWidth,"No student found",$tmp_line);
! 574: }
! 575: }
! 576: }
! 577: } else { # cancel
! 578: $student_id = "";
! 579: $student_name = "";
! 580: }
! 581: return ($student_id,$student_name);
! 582: }
! 583:
! 584:
! 585:
! 586: #
! 587: # INPUT: the class name with full path and the student number
! 588: # OUTPUT: total scores , total possible wights
! 589:
! 590: sub S_CollectSetScores {
! 591: local($classpath,$student_id,$on_screen,$s_limit)=@_;
! 592: local($filename,$found,$classname);
! 593: local($done)=0;
! 594: local($line_cnt,$input_line);
! 595: local(@weights); # the wights array for individual set
! 596: local($valid_weights); # the valid weights for a set
! 597: local($total_weights); # the overall valid weights for all sets
! 598: local(@set_weights); # the array storing all set valid weights
! 599: local($score); # the valid score for a set
! 600: local($total_scores); # the overall valid scores for all sets
! 601: local(@set_scores); # the array storing all set scores
! 602: local($set_idx);
! 603: local($ii,$abscent_cnt,$present_cnt);
! 604: local($s_num,$ans_str,$prefix,$rest);
! 605: local(@ans_char,$ratio,$tmp,$summary_str);
! 606:
! 607: $student_id = uc($student_id);
! 608: $total_scores = 0; $total_weights = 0; # initialize the overall results
! 609: $set_idx = 0;
! 610:
! 611: while( ! $done ) {
! 612: $set_idx++; # start out as set1.db, then add one to it
! 613: if($set_idx <= $s_limit ) { # the limit set is inclusive
! 614: $filename = $classpath . "/records/set" . "$set_idx" . ".db";
! 615: if( -f $filename) { # file exists!
! 616: open(IN, "<$filename") || die "Cannot open file $filename!";
! 617: $line_cnt=0; $found = 0; # for each file opened, initialize $line_cnt and $found
! 618: while ( ($input_line = <IN>) && !$found) {
! 619: $line_cnt++; # add one to line count
! 620: if( $line_cnt == 2 ) { # second line is the weight for each problem
! 621: chomp(); # delete the trailing '\n' char
! 622: (@weights) = split(/ */,$input_line); # split the line into each individual chars
! 623: $valid_weights = 0;
! 624: for($ii=0;$ii<=$#weights;$ii++) {
! 625: $valid_weights += $weights[$ii]; # for now $valid_weights contains the sum
! 626: }
! 627: ## &C_ClearScreen;
! 628: ## print "Second line, $input_line, total weight=$valid_weights\n";
! 629: ## printf "Press RETURN to continue"; $tmp = <>;
! 630: }
! 631: if( $line_cnt > 3) { # start from line 4 is the student data
! 632: chomp($input_line); # delete the trailing '\n' char
! 633: ($prefix,$rest) = split(/,/,$input_line,2); # split the whole line into two parts
! 634: ($s_num,$ans_str) = split(/ /,$prefix,2); # split into two parts
! 635: $s_num = uc($s_num);
! 636: if( $student_id eq $s_num ) { # found the student we want
! 637: ## &C_ClearScreen;
! 638: ## print "FOUND [$input_line] $s_num == $student_id: weight= $valid_weights,ANS=$ans_str\n";
! 639: ## printf "Press RETURN to continue"; $tmp = <>;
! 640: $found = 1; # so we can exit the search through while loop
! 641: (@ans_char) = split(/ */,$ans_str); # split the answer string into individual ans chars
! 642: for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) { # from question 0, 1, to last question -1
! 643: $valid = 'Y' if $ans_char[$ii] ne '-'; # if ans char is different from '-', then
! 644: }
! 645: if( $valid eq 'Y' ) { # don't bother with the record full of '-'s
! 646: for($score=0,$ii=0;$ii<=$#ans_char;$ii++) { # initialize $score and index $ii
! 647:
! 648: if($ans_char[$ii] eq 'Y') {
! 649: $score += $weights[$ii];
! 650: }
! 651: if($ans_char[$ii] eq 'y') {
! 652: $score += $weights[$ii];
! 653: }
! 654: if( $ans_char[$ii] ge '0' && $ans_char[$ii] le '9') {
! 655: $score += $ans_char[$ii];
! 656: }
! 657: if($ans_char[$ii] eq 'E') { # subtract the weight from execused problem
! 658: $valid_weights -= $weights[$ii];
! 659: }
! 660: }
! 661: $total_scores += $score; # add the calculated score to the overall sum
! 662: } else { # end of a valid line
! 663: $score = '-';
! 664: }
! 665: }
! 666: } # end $line_cnt > 3
! 667: } # end while <IN>
! 668: close(IN) || die "Cannot close file $filename!";
! 669: $total_weights += $valid_weights; # add the valid weights for a set to the overall sum
! 670: $set_weights[$set_idx-1] = $valid_weights;
! 671:
! 672: if( $found ) {
! 673: ## push(@set_scores, $score); # push set score into array
! 674: ## push(@set_weights, $valid_weights); # push valid weight for a set into the weight array
! 675: $set_scores[$set_idx-1] = $score;
! 676: } else { # student not found in the setX.db file
! 677: $set_scores[$set_idx-1] = '-';
! 678: }
! 679: } else { # $set_idx > $s_limit
! 680: $done = 1; # exit the $done while loop
! 681: }
! 682: } else {
! 683: $done = 1; # exit the $done while loop
! 684: }
! 685: } # end while ! $done
! 686: # print out the report
! 687: # &C_ClearScreen;
! 688: $abscent_cnt=0;
! 689: $present_cnt=0;
! 690: $summary_str = "";
! 691: print " " x 10 if $on_screen;
! 692: for($ii=0;$ii<=$#set_scores;$ii++) {
! 693: if( $set_scores[$ii] eq '-' || $set_scores[$ii] eq "" ) {
! 694: print " - " if $on_screen;
! 695: $summary_str = "$summary_str" . "x/$set_weights[$ii] ";
! 696: $abscent_cnt++;
! 697: } else {
! 698: printf " %3d", $set_scores[$ii] if $on_screen;
! 699: $summary_str = "$summary_str" . "$set_scores[$ii]/$set_weights[$ii] ";
! 700: $present_cnt++;
! 701: }
! 702: }
! 703: if( $on_screen ) {
! 704: $classname = substr($classpath,-8,8);
! 705: print "\n $classname:";
! 706: for($ii=0;$ii<=$#set_scores;$ii++) {
! 707: print " ---";
! 708: }
! 709: print "\n ";
! 710: for($ii=0;$ii<=$#set_weights;$ii++) {
! 711: printf " %3d", $set_weights[$ii];
! 712: }
! 713: print "\n";
! 714: if($total_weights != 0 ) {
! 715: $ratio = 100.0 * ($total_scores / $total_weights);
! 716: } else {
! 717: $ratio = '-';
! 718: }
! 719: printf " %5d\n", $total_scores if $on_screen;
! 720: printf " ------- = %3.2f%%, scores abscent in %d/%d\n", $ratio, $abscent_cnt, $#set_scores+1;
! 721: printf " %5d\n", $total_weights;
! 722: ## print "Press RETURN to continue"; $tmp = <>;
! 723: }
! 724: return ($total_scores,$total_weights,$abscent_cnt,$#set_scores+1,$summary_str);
! 725: }
! 726:
! 727: #
! 728: # similar to S_CollectSetScores
! 729: #
! 730: sub S_CollectExamScores {
! 731: local($classpath,$student_id)=@_;
! 732: local($filename,$found,$classname);
! 733: local($done)=0;
! 734: local($line_cnt,$input_line);
! 735: local(@weights); # the wights array for individual set
! 736: local($valid_weights); # the valid weights for a set
! 737: local($total_weights); # the overall valid weights for all sets
! 738: local(@set_weights); # the array storing all set valid weights
! 739: local($score); # the valid score for a set
! 740: local($total_scores); # the overall valid scores for all sets
! 741: local(@set_scores); # the array storing all set scores
! 742: local($set_idx);
! 743: local($ii,$var_name);
! 744: local($s_num,$ans_str,$prefix,$rest);
! 745: local($midterm1,$midterm2,$midterm3,$f_score);
! 746: local($m_max1,$m_max2,$m_max3,$f_max);
! 747: local(@ans_char,$ratio,$tmp);
! 748:
! 749: $student_id = uc($student_id);
! 750: $total_scores = 0; $total_weights = 0; # initialize the overall results
! 751: $set_idx = 0;
! 752:
! 753: while( ! $done ) {
! 754: $set_idx++; # start out as set1.db, then add one to it
! 755: if( $set_idx <= $exam_scores_limit_set ) { # $exam_scores_limit_set comes from capa.config
! 756: $filename = $classpath . "/records/set" . "$set_idx" . ".db";
! 757: if( -f $filename) { # file exists!
! 758: open(IN, "<$filename") || die "Cannot open file $filename!";
! 759: $line_cnt=0; $found = 0; # for each file opened, initialize $line_cnt and $found
! 760: while ( ($input_line = <IN>) && !$found) {
! 761: $line_cnt++; # add one to line count
! 762: if( $line_cnt == 2 ) { # second line is the weight for each problem
! 763: chomp(); # delete the trailing '\n' char
! 764: (@weights) = split(/ */,$input_line); # split the line into each individual chars
! 765: $valid_weights = 0;
! 766: for($ii=0;$ii<=$#weights;$ii++) {
! 767: $valid_weights += $weights[$ii]; # for now $valid_weights contains the sum
! 768: }
! 769: }
! 770: if( $line_cnt > 3) { # start from line 4 is the student data
! 771: chomp($input_line); # delete the trailing '\n' char
! 772: ($prefix,$rest) = split(/,/,$input_line,2); # split the whole line into two parts
! 773: ($s_num,$ans_str) = split(/ /,$prefix,2); # split into two parts
! 774: $s_num = uc($s_num);
! 775: if( $student_id eq $s_num ) { # found the student we want
! 776: $found = 1; # so we can exit the search through while loop
! 777: (@ans_char) = split(/ */,$ans_str); # split the answer string into individual ans chars
! 778: for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) { # from question 0, 1, to last question -1
! 779: $valid = 'Y' if $ans_char[$ii] ne '-'; # if ans char is different from '-', then
! 780: }
! 781: if( $valid eq 'Y' ) { # don't bother with the record full of '-'s
! 782: for($score=0,$ii=0;$ii<=$#ans_char;$ii++) { # initialize $score and index $ii
! 783:
! 784: if($ans_char[$ii] eq 'Y') {
! 785: $score += $weights[$ii];
! 786: }
! 787: if($ans_char[$ii] eq 'y') {
! 788: $score += $weights[$ii];
! 789: }
! 790: if( $ans_char[$ii] ge '0' && $ans_char[$ii] le '9') {
! 791: $score += $ans_char[$ii];
! 792: }
! 793: if($ans_char[$ii] eq 'E') { # subtract the weight from execused problem
! 794: $valid_weights -= $weights[$ii];
! 795: }
! 796: }
! 797: $total_scores += $score; # add the calculated score to the overall sum
! 798: } else { # end of a valid line
! 799: $score = '-';
! 800: }
! 801: } # end student number comparison
! 802: } # end $line_cnt > 3
! 803: } # end while <IN>
! 804: close(IN) || die "Cannot close file $filename!";
! 805: $total_weights += $valid_weights; # add the valid weights for a set to the overall sum
! 806: $set_weights[$set_idx-1] = $valid_weights;
! 807: # push(@set_scores, $score); # push set score into array
! 808: # push(@set_weights, $valid_weights); # push valid weight for a set into the weight array
! 809: if( $found ) {
! 810: $set_scores[$set_idx-1] = $score;
! 811: } else { # could not locate the student in the setX.db file
! 812: $set_scores[$set_idx-1] = '-';
! 813: }
! 814: } else { # $set_idx > $exam_scores_limit_set
! 815: $done = 1;
! 816: }
! 817: } else {
! 818: $done = 1; # exit the $done while loop
! 819: }
! 820: } # end while ! $done
! 821:
! 822: # put scores in the global variables: exam_raw1, exam_raw2 ...
! 823: # and maximum weights in variables: exam_raw_max1, exam_raw_max2,..
! 824: # prefix is stored in :
! 825: # $Prefix_name{"Exam_raw_scores"}
! 826: # $Prefix_name{"Exam_raw_max"}
! 827: #
! 828: $Prefix_name{'Exam_raw_scores'} = "exam_raw" if ! defined $Prefix_name{'Exam_raw_scores'};
! 829: $Prefix_name{'Exam_raw_max'} = "exam_raw_max" if ! defined $Prefix_name{'Exam_raw_max'};
! 830: for($ii=0;$ii<=$#set_scores;$ii++) {
! 831: $set_idx = $ii+1;
! 832: $var_name = "$Prefix_name{'Exam_raw_scores'}" . "$set_idx";
! 833: ${$var_name} = $set_scores[$ii];
! 834: $var_name = "$Prefix_name{'Exam_raw_max'}" . "$set_idx";
! 835: ${$var_name} = $set_weights[$ii];
! 836: }
! 837: #
! 838: # initialize these local variables
! 839: #
! 840: $midterm1 = '-'; $m_max1 = '-';
! 841: $midterm2 = '-'; $m_max2 = '-';
! 842: $midterm3 = '-'; $m_max3 = '-';
! 843: $f_score = '-'; $f_max = '-';
! 844: # After we placed raw scores into the global variables exam_raw1, exam_raw2 ...
! 845: # we can then, evaluate the definitions of midterm1, midterm2 and midterm3 from capa.config
! 846: if($#set_scores >= 1) { # at least 2 sets
! 847: $midterm1 = eval $P_code{'midterm1'};
! 848: $var_name = "$Prefix_name{'Exam_raw_max'}" . "1"; # for max possible scores, just pick a set
! 849: $m_max1 = ${$var_name};
! 850: if($#set_scores >= 3) { # at least 4 sets
! 851: $midterm2 = eval $P_code{'midterm2'};
! 852: $var_name = "$Prefix_name{'Exam_raw_max'}" . "3"; # for max possible scores, just pick a set
! 853: $m_max2 = ${$var_name};
! 854: if($#set_scores >= 5) { # at least 6 sets
! 855: $midterm3 = eval $P_code{'midterm3'};
! 856: $var_name = "$Prefix_name{'Exam_raw_max'}" . "5"; # for max possible scores, just pick a set
! 857: $m_max3 = ${$var_name};
! 858: if($#set_scores == 6 ) { # the 7th set
! 859: # in capa.config a variable $final_exam is defined as
! 860: # the same with $exam_raw7
! 861: ## $var_name = "$Prefix_name{'Exam_raw_scores'}" . "7";
! 862: ## $f_score = ${$var_name};
! 863: $f_score = eval $P_code{'final_exam'};
! 864: $var_name = "$Prefix_name{'Exam_raw_max'}" . "7";
! 865: $f_max = ${$var_name};
! 866: } else { # only 6 sets
! 867:
! 868: }
! 869: } else { # 4 or 5 sets
! 870:
! 871: }
! 872: } else { # 2 or 3 sets
! 873:
! 874: }
! 875: } else { # 0 or 1 sets
! 876:
! 877: }
! 878: return ($midterm1,$m_max1,$midterm2,$m_max2,$midterm3,$m_max3,$f_score,$f_max,$#set_scores+1);
! 879:
! 880: }
! 881:
! 882: #
! 883: # Menu item: capastat
! 884: # ($Q_cnt,$L_cnt) = &S_ScanSetDB($Sfullpath);
! 885: # Percentage_Scores($Set);
! 886: # S_Average($Q_cnt,$L_cnt);
! 887: #
! 888: # INPUT: the setX.db file name with full path
! 889: #
! 890: sub S_ScanSetDB {
! 891: local($filename)=@_;
! 892: local($line_cnt)=0;
! 893: local($valid_cnt)=0;
! 894: local($valid);
! 895: local($ii);
! 896: local($s_num,$ans_str,$prefix,$rest);
! 897: local(@ans_char,@tries);
! 898: local($score);
! 899:
! 900: for($ii=0;$ii<=99;$ii++) {
! 901: $Total_try[$ii]=0;
! 902: $Yes_cnt[$ii]=0;
! 903: $yes_cnt[$ii]=0;
! 904: for($jj=0;$jj<=99;$jj++) {
! 905: $Student_cnt[$ii][$jj]=0;
! 906: $Student_try[$ii][$jj]=0;
! 907: }
! 908: }
! 909: $Total_weight=0;
! 910: $Total_scores=0;
! 911:
! 912: open(IN, "<$filename") || die "Cannot open file $filename!";
! 913: while (<IN>) {
! 914: $line_cnt++;
! 915: if( $line_cnt == 2 ) {
! 916: chomp();
! 917: (@Weight) = split(/ */);
! 918: }
! 919: if( $line_cnt > 3) {
! 920: chomp();
! 921: ($prefix,$rest) = split(/,/,$_,2);
! 922: ($s_num,$ans_str) = split(/ /,$prefix,2);
! 923: (@ans_char) = split(/ */,$ans_str);
! 924: (@tries) = split(/,/,$rest);
! 925: for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) {
! 926: $valid = 'Y' if $ans_char[$ii] ne '-';
! 927: }
! 928: if( $valid eq 'Y' ) {
! 929: for($score=0,$ii=0;$ii<=$#tries;$ii++) {
! 930: $Student_cnt[$ii][$tries[$ii]]++;
! 931: $Student_try[$valid_cnt][$ii] = $tries[$ii];
! 932: $Total_try[$ii] += $tries[$ii];
! 933: $Total_weight += $Weight[$ii];
! 934: if($ans_char[$ii] eq 'Y') {
! 935: $Yes_cnt[$ii]++;
! 936: $score += $Weight[$ii];
! 937: }
! 938: if($ans_char[$ii] eq 'y') {
! 939: $yes_cnt[$ii]++;
! 940: $score += $Weight[$ii];
! 941: }
! 942: if( $ans_char[$ii] ge '0' && $ans_char[$ii] le '9') {
! 943: $score += $ans_char[$ii];
! 944: }
! 945: }
! 946: $Total_scores += $score;
! 947: $Entry{"$valid_cnt"} = "$s_num\n" . "$ans_str," . " $rest\n";
! 948: $Score{"$valid_cnt"} = $score;
! 949: $valid_cnt++;
! 950: }
! 951: }
! 952: }
! 953: close(IN) || die "Cannot close $filename file!";
! 954: return ($#tries+1,$valid_cnt);
! 955: }
! 956:
! 957:
! 958: $MAX_TRIES = 99;
! 959:
! 960: sub S_Average {
! 961: local($q_cnt,$l_cnt)=@_;
! 962: local($ii,$jj);
! 963: local(@s_cnt,@avg);
! 964: local(@sd, $sum);
! 965: local($sq);
! 966: local(@sd3,$tmp1,$tmp2,$done);
! 967:
! 968: for($ii=0;$ii<$q_cnt;$ii++) {
! 969: $s_cnt[$ii] = 0;
! 970: $avg[$ii] = 0.0;
! 971: $Max_try[$ii] = 0;
! 972: for($jj=1;$jj<$MAX_TRIES;$jj++) { # ignore the 0 try entry
! 973: if( $Student_cnt[$ii][$jj] > 0 ) {
! 974: $avg[$ii] += $jj*$Student_cnt[$ii][$jj];
! 975: $s_cnt[$ii] += $Student_cnt[$ii][$jj];
! 976: }
! 977: }
! 978: if( $s_cnt[$ii] > 0 ) { # avoid division by zero
! 979: $avg[$ii] = $avg[$ii] / $s_cnt[$ii];
! 980: }
! 981: }
! 982:
! 983: for($ii=0;$ii<$q_cnt;$ii++) {
! 984: $sd[$ii] = 0.0;
! 985: $sum = 0.0;
! 986: for($jj=0;$jj<$l_cnt;$jj++) {
! 987: $Max_try[$ii] = ($Student_try[$jj][$ii] > $Max_try[$ii]? $Student_try[$jj][$ii] : $Max_try[$ii]);
! 988: if( $Student_try[$jj][$ii] > 0 ) {
! 989: $sq = ($Student_try[$jj][$ii] - $avg[$ii])*($Student_try[$jj][$ii] - $avg[$ii]);
! 990: $sum += $sq;
! 991: }
! 992: if( $s_cnt[$ii] > 1 ) {
! 993: $sd[$ii] = $sum / ($s_cnt[$ii] - 1.0 );
! 994: }
! 995: if( $sd[$ii] > 0 ) {
! 996: $sd[$ii] = sqrt( $sd[$ii] );
! 997: }
! 998: }
! 999: }
! 1000:
! 1001: for($ii=0;$ii<$q_cnt;$ii++) {
! 1002: $sd3[$ii] = 0.0;
! 1003: $sum = 0.0;
! 1004: for($jj=0;$jj<$l_cnt;$jj++) {
! 1005: if( $Student_try[$jj][$ii] > 0 ) {
! 1006: $tmp1 = $Student_try[$jj][$ii] - $avg[$ii];
! 1007: $tmp2 = $tmp1*$tmp1*$tmp1;
! 1008: $sum = $sum + $tmp2;
! 1009: }
! 1010: if( $s_cnt[$ii] > 0 && $sd[$ii] != 0.0 ) {
! 1011: $sd3[$ii] = $sum/$s_cnt[$ii] ;
! 1012: $sd3[$ii] = $sd3[$ii] / ($sd[$ii]*$sd[$ii]*$sd[$ii]);
! 1013: }
! 1014: }
! 1015: }
! 1016:
! 1017: print "This is the statistics for each problem:\n";
! 1018: print "Prob\# MxTries avg. s.d. s.k. \#Stdnts ";
! 1019: print " \#Yes \#yes Tries DoDiff\n";
! 1020: for($ii=0;$ii<$q_cnt;$ii++) {
! 1021: if( $Total_try[$ii] > 0 ) {
! 1022: ## $dod = 1-($Yes_cnt[$ii] + $yes_cnt[$ii]) / $Total_try[$ii];
! 1023: $dod = $Total_try[$ii]/(0.1 + $Yes_cnt[$ii] + $yes_cnt[$ii]);
! 1024: }
! 1025: printf "P %2d:",$ii+1;
! 1026: printf "%7d %8.2f %7.2f %6.2f %5d %5d %5d %5d %5.1f\n",
! 1027: $Max_try[$ii],$avg[$ii],$sd[$ii],$sd3[$ii],$s_cnt[$ii],$Yes_cnt[$ii],$yes_cnt[$ii],
! 1028: $Total_try[$ii],$dod;
! 1029:
! 1030: }
! 1031: printf "Press RETURN to continue"; $done = <>;
! 1032: }
! 1033:
! 1034: sub Percentage_Scores {
! 1035: local($set,$valid_cnt)=@_;
! 1036: local($ratio);
! 1037: local($done);
! 1038:
! 1039: if($Total_weight > 0 ) {
! 1040: $ratio = $Total_scores / $Total_weight;
! 1041: $ratio = $ratio * 100.0;
! 1042: }
! 1043:
! 1044: printf "\nThe percentage score (total scores / total valid weights) for set%d.db is:\n %7.2f%%\n",$set,$ratio;
! 1045: printf "The number of valid records for set%d.db is: %d\n", $set, $valid_cnt;
! 1046: printf "Press RETURN to continue"; $done=<>;
! 1047: }
! 1048:
! 1049:
! 1050: sub Large_Tries {
! 1051: local($t,$n,$q_cnt,$l_cnt)=@_;
! 1052: local($ii);
! 1053:
! 1054: print "\nHere is a list of students who attempts $t tries more than $n times: \n\n";
! 1055:
! 1056: for ($i=0;$i<$l_cnt;$i++){
! 1057: $count=0;
! 1058: $credit=0;
! 1059: for ($j=0;$j<$q_cnt;$j++){
! 1060: if ($Student_try[$i][$j]>= $t){
! 1061: $count++;
! 1062: }
! 1063: }
! 1064: if ($count >= $n){
! 1065: print "($Score{$i}) $Entry{$i} \n";
! 1066: }
! 1067: }
! 1068:
! 1069: }
! 1070:
! 1071:
! 1072: sub S_ScanLogDB {
! 1073: local($filename)=@_;
! 1074: local($line_cnt)=0;
! 1075: local($s_num,$dow,$mon,$sp,$day,$time,$yr,$ans_str);
! 1076: local(@ans_char);
! 1077: local($ii,$first,$done);
! 1078: local($Yes_cnt[99],$No_cnt[99],$U_cnt[99],$S_cnt[99],$u_cnt[99]);
! 1079: local($Y_total,$N_total,$U_total,$u_total,$S_total);
! 1080:
! 1081: $Y_total=0; $N_total=0; $U_total=0; $u_total=0; $S_total=0;
! 1082: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1083: for($ii=0;$ii<=99;$ii++) {
! 1084: $Yes_cnt[$ii] = 0; $No_cnt[$ii] = 0;
! 1085: $U_cnt[$ii]=0; $u_cnt[$ii]=0; $S_cnt[$ii]=0;
! 1086: }
! 1087: while (<IN>) {
! 1088: $line_cnt++;
! 1089: chomp();
! 1090: $ans_str = substr($_,35);
! 1091: ## ($first,$ans_str) = split(/1996 /); # depends on this special pattern
! 1092: # print "$ans_str\n";
! 1093: (@ans_char) = split(/ */,$ans_str);
! 1094:
! 1095: for($ii=0;$ii<=$#ans_char;$ii++) {
! 1096:
! 1097: if($ans_char[$ii] eq 'Y') {
! 1098: $Yes_cnt[$ii]++;
! 1099: $Y_total++;
! 1100: }
! 1101: if($ans_char[$ii] eq 'N') {
! 1102: $No_cnt[$ii]++;
! 1103: $N_total++;
! 1104: }
! 1105: if($ans_char[$ii] eq 'U') {
! 1106: $U_cnt[$ii]++;
! 1107: $U_total++;
! 1108: }
! 1109: if($ans_char[$ii] eq 'u') {
! 1110: $u_cnt[$ii]++;
! 1111: $u_total++;
! 1112: }
! 1113: if($ans_char[$ii] eq 'S') {
! 1114: $S_cnt[$ii]++;
! 1115: $S_total++;
! 1116: }
! 1117: }
! 1118: }
! 1119: close(IN) || die "Cannot close file $filename!";
! 1120: print "Prob #: #Y #N #S #U #u\n";
! 1121: for($ii=0;$ii<=$#ans_char;$ii++) {
! 1122: printf " %2d: %6d %6d %6d %6d %6d\n",
! 1123: $ii+1, $Yes_cnt[$ii], $No_cnt[$ii], $S_cnt[$ii], $U_cnt[$ii], $u_cnt[$ii];
! 1124: }
! 1125: print "=" x 45 . "\n";
! 1126: printf " Total: %6d %6d %6d %6d %6d\n", $Y_total, $N_total, $S_total, $U_total, $u_total;
! 1127: printf "Press RETURN to continue"; $done = <>;
! 1128:
! 1129: return ($Y_total,$N_total,$S_total,$U_total,$u_total);
! 1130: }
! 1131:
! 1132: sub S_StudentLoginData {
! 1133: local($filename,$student_id)=@_;
! 1134: local($Y_total,$N_total,$S_total,$U_total,$u_total);
! 1135: local($ans_str,@ans_char);
! 1136: local($ii,$s_id);
! 1137:
! 1138: $Y_total=0; $N_total=0; $U_total=0; $u_total=0; $S_total=0;
! 1139: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1140: while (<IN>) {
! 1141: chomp();
! 1142: $s_id = substr($_,0,9); # student number begins at column 0 and has 9 chars
! 1143: $s_id = uc($s_id);
! 1144: $student_id = uc($student_id);
! 1145: if( $student_id eq $s_id) {
! 1146: $ans_str = substr($_,35); # the answer string begins at column 35 (count from 0)
! 1147: (@ans_char) = split(/ */,$ans_str);
! 1148: for($ii=0;$ii<=$#ans_char;$ii++) {
! 1149: if($ans_char[$ii] eq 'Y') {
! 1150: $Y_total++;
! 1151: }
! 1152: if($ans_char[$ii] eq 'N') {
! 1153: $N_total++;
! 1154: }
! 1155: if($ans_char[$ii] eq 'U') {
! 1156: $U_total++;
! 1157: }
! 1158: if($ans_char[$ii] eq 'u') {
! 1159: $u_total++;
! 1160: }
! 1161: if($ans_char[$ii] eq 'S') {
! 1162: $S_total++;
! 1163: }
! 1164: } # end for each problem
! 1165: } # end student number matches
! 1166: } # end while
! 1167: close(IN) || die "Cannot close file $filename!";
! 1168: return ($Y_total,$N_total,$S_total,$U_total,$u_total);
! 1169: }
! 1170:
! 1171: #
! 1172: sub S_LoginAnalysis {
! 1173: local($classpath,$student_id,$s_limit)=@_;
! 1174: local($Y_set,$N_set,$S_set,$U_set,$u_set);
! 1175: local($set_idx,$no_log,$no_weblog,$done,$tmp);
! 1176:
! 1177: print "Login analysis: telnet session web session\n\n";
! 1178: print " set #: #Y #N #S #U #u #Y #N #S #U #u\n";
! 1179: $set_idx=0; $done=0;
! 1180: while (! $done ) {
! 1181: $set_idx++;
! 1182: if( $set_idx <= $s_limit) {
! 1183: printf " %2d: ", $set_idx;
! 1184: $filename= $classpath . "/records/log" . "$set_idx" . ".db";
! 1185: if(-f $filename) {
! 1186: ($Y_set,$N_set,$S_set,$U_set,$u_set)=S_StudentLoginData($filename,$student_id);
! 1187: printf "%4d %4d %4d %4d %4d", $Y_set,$N_set,$S_set,$U_set,$u_set;
! 1188: $no_log = 0;
! 1189: } else {
! 1190: print "=" x 24;
! 1191: $no_log = 1;
! 1192: }
! 1193: print " " x 4;
! 1194: $filename= $classpath . "/records/weblog" . "$set_idx" . ".db";
! 1195: if(-f $filename) {
! 1196: ($Y_set,$N_set,$S_set,$U_set,$u_set)= S_StudentLoginData($filename,$student_id);
! 1197: printf "%4d %4d %4d %4d %4d", $Y_set,$N_set,$S_set,$U_set,$u_set;
! 1198: $no_weblog = 0;
! 1199: } else {
! 1200: print "=" x 24;
! 1201: $no_weblog = 1;
! 1202: }
! 1203: print "\n";
! 1204: if( $no_log && $no_weblog ) { $done = 1; };
! 1205: } else { # $set_idx > $s_limit
! 1206: $done = 1;
! 1207: }
! 1208: }
! 1209:
! 1210: printf "Press RETURN to continue"; $tmp = <>;
! 1211: }
! 1212:
! 1213: # It pulls out the data base entry from setX.db files
! 1214: sub S_StudentSetAnalysis {
! 1215: local($classpath,$student_id,$s_limit)=@_;
! 1216: local($filename);
! 1217: local($set_idx,$done);
! 1218: local($line_cnt,$found,$input_line);
! 1219: local($s_num,$data,$ans_str,$try_str,$tmp);
! 1220:
! 1221: $set_idx=0; $student_id = uc($student_id);
! 1222: print " set #:\n";
! 1223: while(! $done) {
! 1224: $set_idx++;
! 1225: if( $set_idx <= $s_limit) {
! 1226: $filename= $classpath . "/records/set" . "$set_idx" . ".db";
! 1227: if(-f $filename) {
! 1228: printf " %2d: ", $set_idx;
! 1229: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1230: $line_cnt=0; $found = 0; # for each file opened, initialize $line_cnt and $found
! 1231: while ( ($input_line = <IN>) && !$found) {
! 1232: $line_cnt++; # add one to line count
! 1233: if( $line_cnt > 3) { # start from line 4 is the student data
! 1234: chomp($input_line); # delete the trailing '\n' char
! 1235: $s_num = substr($input_line,0,9);
! 1236: $s_num = uc($s_num);
! 1237: if( $student_id eq $s_num ) {
! 1238: $found = 1;
! 1239: $data = substr($input_line,10);
! 1240: ($ans_str,$try_str) = split(/,/,$data,2);
! 1241: print "$ans_str\n $try_str\n";
! 1242: }
! 1243: } # $line_cnt > 3
! 1244: } # end while $input_line and ! $found
! 1245: close(IN) || die "Cannot close file $filename!";
! 1246: if(! $found ) { # student record entry not in the setX.db file ==> two empty lines
! 1247: print "\n\n";
! 1248: }
! 1249: } else { # $filename does not exist
! 1250: $done = 1;
! 1251: }
! 1252: } else { # $set_idx > $s_limit
! 1253: $done = 1;
! 1254: }
! 1255: }
! 1256: printf "Press RETURN to continue"; $tmp = <>;
! 1257: }
! 1258:
! 1259: #
! 1260: # INPUTS: class name with full path, set number
! 1261: #
! 1262: sub S_ItemAnalysis {
! 1263: local($classpath,$set)=@_;
! 1264: local($filename,$found,$classname);
! 1265: local($done)=0;
! 1266: local($line_cnt,$input_line);
! 1267: local($valid,$valid_cnt);
! 1268: local(@weights); # the wights array for individual set
! 1269: local($valid_weights); # the valid weights for a set
! 1270: local($total_weights); # the overall valid weights for all sets
! 1271: local(@set_weights); # the array storing all set valid weights
! 1272: local($score); # the valid score for a set
! 1273: local($total_scores); # the overall valid scores for all sets
! 1274: local(@set_scores); # the array storing all set scores
! 1275: local($diff,$disc);
! 1276: local($ii,$upper_percent,$lower_percent);
! 1277: local($s_num,$ans_str,$prefix,$rest);
! 1278: local(@ans_char,$ratio,$tmp);
! 1279: local($Y_cnt[100],$N_cnt[100]);
! 1280: local($Ycnt_upper[100],$Ycnt_lower[100],$tmp_total);
! 1281: local($Y_total,$N_total);
! 1282: local($upperpart_cnt,$lowerpart_limit);
! 1283: local(%s_db);
! 1284:
! 1285: $total_scores = 0; $total_weights = 0; # initialize the overall results
! 1286: $upper_percent = 0.0; $lower_percent = 0.0;
! 1287:
! 1288: for($ii=0;$ii<100;$ii++) {
! 1289: $Y_cnt[$ii] = 0; $N_cnt[$ii] = 0; $Ycnt_upper[$ii] = 0.0; $Ycnt_lower[$ii] = 0.0;
! 1290: }
! 1291: $filename = $classpath . "/records/set" . "$set" . ".db";
! 1292: if( -f $filename) { # file exists!
! 1293: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1294: $valid_cnt = 0; # initialize $valid_cnt
! 1295: $line_cnt=0; # initialize $line_cnt
! 1296: while (<IN>) {
! 1297: $line_cnt++; # add one to line count
! 1298: if( $line_cnt == 2 ) { # second line is the weight for each problem
! 1299: chomp(); # delete the trailing '\n' char
! 1300: (@weights) = split(/ */); # split the line into each individual chars
! 1301: $valid_weights = 0;
! 1302: for($ii=0;$ii<=$#weights;$ii++) {
! 1303: $valid_weights += $weights[$ii]; # for now $valid_weights contains the sum
! 1304: }
! 1305: }
! 1306: if( $line_cnt > 3) { # start from line 4 is the student data
! 1307: chomp(); # delete the trailing '\n' char
! 1308: ($prefix,$rest) = split(/,/,$_,2); # split the whole line into two parts
! 1309: ($s_num,$ans_str) = split(/ /,$prefix,2); # split into two parts
! 1310: $s_num = uc($s_num);
! 1311:
! 1312: ### print "$ans_str\n";
! 1313: (@ans_char) = split(/ */,$ans_str); # split the answer string into in dividual ans chars
! 1314: for($valid = 'N', $ii=0;$ii<=$#ans_char;$ii++) { # from question 0, 1 , to last question -1
! 1315: $valid = 'Y' if $ans_char[$ii] ne '-'; # if ans char is different from '-', then
! 1316: }
! 1317: if( $valid eq 'Y' ) { # don't bother with the record full of '-'s
! 1318: $valid_cnt++;
! 1319: for($score=0,$ii=0;$ii<=$#ans_char;$ii++) { # initialize $score and index $ii
! 1320:
! 1321: if($ans_char[$ii] eq 'Y' || $ans_char[$ii] eq 'y') {
! 1322: $score += $weights[$ii];
! 1323: $Y_cnt[$ii]++;
! 1324: $Y_total++;
! 1325: }
! 1326: if( $ans_char[$ii] eq 'N' || $ans_char[$ii] eq 'n' ||
! 1327: $ans_char[$ii] eq '0' ) {
! 1328: $N_cnt[$ii]++;
! 1329: $N_total++;
! 1330: }
! 1331: if( $ans_char[$ii] gt '0' && $ans_char[$ii] le '9') {
! 1332: $score += $ans_char[$ii];
! 1333: if( $ans_char[$ii] eq $weights[$ii] ) {
! 1334: $Y_cnt[$ii]++;
! 1335: $Y_total++;
! 1336: } else {
! 1337: $N_cnt[$ii]++;
! 1338: $N_total++;
! 1339: }
! 1340: }
! 1341: if($ans_char[$ii] eq 'E') { # subtract the weight from execused problem
! 1342: $valid_weights -= $weights[$ii];
! 1343: }
! 1344: } # end of score calculation
! 1345:
! 1346: $sort_key = sprintf "%05d%s", $score,$s_num;
! 1347: $s_db{$sort_key} = "$ans_str";
! 1348:
! 1349: }
! 1350: } # end $line_cnt > 3
! 1351: } # end while <IN>
! 1352: close(IN) || die "Cannot close file $filename!";
! 1353:
! 1354: for($ii=0;$ii<100;$ii++) {
! 1355: ## $Y_cnt[$ii]=0; $N_cnt[$ii]=0;
! 1356: $Ycnt_upper[$ii] = 0; $Ycnt_lower[$ii] = 0;
! 1357: }
! 1358: $upperpart_cnt = int(0.27 * $valid_cnt); # upper 27 percent
! 1359: $lowerpart_limit = ($valid_cnt - $upperpart_cnt); # beyond 73 percent
! 1360: ### open(DBUG, ">/tmp/f.DBUG") || die "Cannot open /tmp/f.DBUG file!";
! 1361: $line_cnt=0;
! 1362: foreach $sort_key (reverse sort keys %s_db) {
! 1363: $line_cnt++;
! 1364: ### print DBUG "$sort_key\[$s_db{$sort_key}\]";
! 1365:
! 1366: $ans_str = "$s_db{$sort_key}";
! 1367: (@ans_char) = split(/ */,$ans_str);
! 1368: for($ii=0;$ii<=$#ans_char;$ii++) {
! 1369: if( ($ans_char[$ii] eq 'Y') || ($ans_char[$ii] eq 'y') ||
! 1370: ($ans_char[$ii] eq $weights[$ii] ) ) { ## only if they got a full credit that
! 1371: ## we count it as 'Y'
! 1372:
! 1373: if($line_cnt <= $upperpart_cnt) {
! 1374: $Ycnt_upper[$ii]++;
! 1375: } elsif ( $line_cnt > $lowerpart_limit ) {
! 1376: $Ycnt_lower[$ii]++;
! 1377: }
! 1378: }
! 1379: ### print DBUG " $Ycnt_upper[$ii]/$Ycnt_lower[$ii] ";
! 1380: } # end for $ii
! 1381: ### print DBUG "\n";
! 1382: } #end foreach
! 1383: ### close(DBUG);
! 1384: print " There are $valid_cnt entries in file $filename\n";
! 1385: printf " The upper 27%% has %d records, the lower 27%% has %d records\n", $upperpart_cnt, $valid_cnt-$lowerpart_limit;
! 1386: print " question \# DoDiff. Disc. Factor (%upper - %lower) [#records,#records]\n";
! 1387:
! 1388: for($ii=0;$ii<=$#ans_char;$ii++) {
! 1389: $tmp_total = $N_cnt[$ii] + $Y_cnt[$ii];
! 1390: if( $tmp_total > 0 ) {
! 1391: $diff = 100.0*($N_cnt[$ii] / ($N_cnt[$ii] + $Y_cnt[$ii]));
! 1392: } else {
! 1393: $diff = '-';
! 1394: }
! 1395: $upper_percent = 100.0 * ($Ycnt_upper[$ii] /$upperpart_cnt);
! 1396: $lower_percent = 100.0 * ($Ycnt_lower[$ii] /$upperpart_cnt);
! 1397: $disc = $upper_percent - $lower_percent;
! 1398: printf " %2d: ", $ii+1;
! 1399: printf "%6.1f %5.1f (% 5.1f - % 5.1f) [%4d,%4d]\n",
! 1400: $diff, $disc,$upper_percent,$lower_percent,$Ycnt_upper[$ii],$Ycnt_lower[$ii];
! 1401: }
! 1402: printf "Press RETURN to continue"; $tmp = <>;
! 1403: } else { # file does not exist!
! 1404: print "FILE: $filename does not exist!\n";
! 1405: printf "Press RETURN to continue"; $tmp = <>;
! 1406: }
! 1407: }
! 1408:
! 1409: #
! 1410: # INPUTS: class name with full path, set number
! 1411: #
! 1412: sub S_SetCorrelation {
! 1413: local($classpath,$set)=@_;
! 1414: local($filename);
! 1415: local($line_cnt);
! 1416: local($data,$ans_str,@ans_char,$try_str);
! 1417: local($ii,$jj,$question_cnt);
! 1418: local($index_key,@weights);
! 1419: local($first_char,$second_char);
! 1420: local(%corr,%valid_cnt,$ratio,$tmp,$tmp_len,$ratio_str);
! 1421:
! 1422: $filename= $classpath . "/records/set" . "$set" . ".db";
! 1423:
! 1424: if(-f $filename) {
! 1425: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1426: $line_cnt=0;
! 1427: while(<IN>) {
! 1428: $line_cnt++;
! 1429: if( $line_cnt == 2 ) { # second line is the weight for each problem
! 1430: chomp(); # delete the trailing '\n' char
! 1431: (@weights) = split(/ */); # split the line into each individual chars
! 1432: }
! 1433: if( $line_cnt > 3) {
! 1434: chomp();
! 1435: $data = substr($_,10); # skip over student number
! 1436: ($ans_str,$try_str) = split(/,/,$data,2);
! 1437: (@ans_char) = split(/ */,$ans_str);
! 1438: $question_cnt = $#ans_char;
! 1439: for($ii=0;$ii<$#ans_char;$ii++) {
! 1440: for($jj=$ii+1;$jj<=$#ans_char;$jj++) {
! 1441: $index_key = "$ii" . "$jj";
! 1442: if( $ans_char[$ii] eq '-' || $ans_char[$ii] eq 'E' ) {
! 1443: # do nothing
! 1444: } else {
! 1445: if( $ans_char[$ii] gt '0' && $ans_char[$ii] le '9') {
! 1446: if( $ans_char[$ii] eq $weights[$ii] ) {
! 1447: $first_char = 'Y';
! 1448: } else {
! 1449: $first_char = 'N';
! 1450: }
! 1451: } elsif ($ans_char[$ii] eq '0') {
! 1452: $first_char = 'N';
! 1453: } elsif ($ans_char[$ii] eq 'y' || $ans_char[$ii] eq 'n') {
! 1454: $first_char = uc($ans_char[$ii]);
! 1455: } else {
! 1456: $first_char = $ans_char[$ii];
! 1457: }
! 1458: if( $ans_char[$jj] eq '-' || $ans_char[$jj] eq 'E' ) {
! 1459: # do nothing
! 1460: } else {
! 1461: if( $ans_char[$jj] gt '0' && $ans_char[$jj] le '9') {
! 1462: if( $ans_char[$jj] eq $weights[$jj] ) {
! 1463: $second_char = 'Y';
! 1464: } else {
! 1465: $second_char = 'N';
! 1466: }
! 1467: } elsif ($ans_char[$jj] eq '0') {
! 1468: $second_char = 'N';
! 1469: } elsif ($ans_char[$jj] eq 'y' || $ans_char[$jj] eq 'n') {
! 1470: $second_char = uc($ans_char[$jj]);
! 1471: } else {
! 1472: $second_char = $ans_char[$jj];
! 1473: }
! 1474: if( $first_char eq $second_char ) {
! 1475: if(defined $corr{$index_key} ) {
! 1476: $corr{$index_key}++;
! 1477: } else {
! 1478: $corr{$index_key} = 1;
! 1479: }
! 1480: } else {
! 1481: if(defined $corr{$index_key} ) {
! 1482: $corr{$index_key}--;
! 1483: } else {
! 1484: $corr{$index_key} = -1;
! 1485: }
! 1486: }
! 1487: # add one count to valid_count
! 1488: if(defined $valid_cnt{$index_key}) {
! 1489: $valid_cnt{$index_key}++;
! 1490: } else {
! 1491: $valid_cnt{$index_key} = 1;
! 1492: }
! 1493: }
! 1494: }
! 1495: } # end $jj loop
! 1496: } # end $ii loop
! 1497: } # end $line_cnt > 3
! 1498: } # end while <IN>
! 1499: close(IN) || die "Cannot close file $filename!";
! 1500: # print out the correlation matrix
! 1501:
! 1502: print " ";
! 1503: for($ii=1;$ii<=$question_cnt;$ii++) {
! 1504: print " " x 4;
! 1505: printf "%2d", $ii+1;
! 1506: }
! 1507: print "\n";
! 1508: # --------------------------------------
! 1509: for($ii=0;$ii<$question_cnt;$ii++) {
! 1510: printf " %2d:", $ii+1;
! 1511: print " " x ($ii);
! 1512: for($jj=$ii+1;$jj<=$question_cnt;$jj++) {
! 1513: $index_key = "$ii" . "$jj";
! 1514: if( defined $corr{$index_key} ) {
! 1515: $ratio = $corr{$index_key} / $valid_cnt{$index_key};
! 1516: printf " % .2f", $ratio;
! 1517: } else {
! 1518: print " ----";
! 1519: }
! 1520: }
! 1521: print "\n";
! 1522: }
! 1523: printf "Press RETURN to continue"; $tmp = <>;
! 1524: } else { # file exists!
! 1525: print "FILE: $filename does not exist!\n";
! 1526: printf "Press RETURN to continue"; $tmp = <>;
! 1527: }
! 1528: }
! 1529:
! 1530: # INPUTS: class name with full path, set number
! 1531: #
! 1532: # r = \frac{\sum{x_i y_i} - \frac{(\sum x_i)(\sum y_i)}{n}}{\sqrt{(\sum x_i^2 - \frac{}{}}}
! 1533: #
! 1534: # corr = (sum of prod_xy - (sum_x*sum_y / n) ) / sqrt( (sum of sqr_x - (sum_x*sum_x/n))*
! 1535: #
! 1536: sub S_SetCorrelationStatistics {
! 1537: local($classpath,$set)=@_;
! 1538: local($filename);
! 1539: local($line_cnt);
! 1540: local($data,$ans_str,@ans_char,$try_str);
! 1541: local($ii,$jj,$question_cnt);
! 1542: local($index_key,@weights);
! 1543: local($x_data,$y_data);
! 1544: local(%valid_cnt,$ratio,$tmp,$tmp_len,$ratio_str);
! 1545: local(%prod_xy,%sum_x,%sum_y,%sum_x2,%sum_y2);
! 1546: local($upper_part,$lower_part);
! 1547:
! 1548: $filename= $classpath . "/records/set" . "$set" . ".db";
! 1549:
! 1550: if(-f $filename) {
! 1551: open(IN, "<$filename") || die "Cannot open file $filename!";
! 1552: $line_cnt=0;
! 1553: while(<IN>) {
! 1554: $line_cnt++;
! 1555: if( $line_cnt == 2 ) { # second line is the weight for each problem
! 1556: chomp(); # delete the trailing '\n' char
! 1557: (@weights) = split(/ */); # split the line into each individual chars
! 1558: }
! 1559: if( $line_cnt > 3) {
! 1560: chomp();
! 1561: $data = substr($_,10); # skip over student number
! 1562: ($ans_str,$try_str) = split(/,/,$data,2);
! 1563: (@ans_char) = split(/ */,$ans_str);
! 1564: $question_cnt = $#ans_char;
! 1565: for($ii=0;$ii<$#ans_char;$ii++) {
! 1566: for($jj=$ii+1;$jj<=$#ans_char;$jj++) {
! 1567: $index_key = "$ii" . "$jj";
! 1568: if( $ans_char[$ii] eq '-' || $ans_char[$ii] eq 'E' ) {
! 1569: # do nothing
! 1570: } else { ## $ans_char[$ii] is one of 0 .. 9, Y, y, N, n
! 1571: if( $ans_char[$jj] eq '-' || $ans_char[$jj] eq 'E' ) {
! 1572: # do nothing
! 1573: } else {
! 1574: if( $ans_char[$ii] eq 'Y' || $ans_char[$ii] eq 'y' ) {
! 1575: $x_data = $weights[$ii];
! 1576: } elsif ( $ans_char[$ii] eq 'N' || $ans_char[$ii] eq 'n' ) {
! 1577: $x_data = 0;
! 1578: } else { ## must be in 0 .. 9
! 1579: $x_data = $ans_char[$ii];
! 1580: }
! 1581: if( $ans_char[$jj] eq 'Y' || $ans_char[$jj] eq 'y' ) {
! 1582: $y_data = $weights[$jj];
! 1583: } elsif ( $ans_char[$jj] eq 'N' || $ans_char[$jj] eq 'n' ) {
! 1584: $y_data = 0;
! 1585: } else { ## must be in 0 .. 9
! 1586: $y_data = $ans_char[$jj];
! 1587: }
! 1588: if(defined $prod_xy{$index_key}) {
! 1589: if ( $ii == 3 && $jj == 7 ) {
! 1590: printf "%f %f %f\n",$x_data,$y_data,$prod_xy{$index_key}
! 1591: }
! 1592: $prod_xy{$index_key} += ($x_data * $y_data);
! 1593: } else {
! 1594: if ( $ii == 3 && $jj == 7 ) {
! 1595: printf "%f %f %f\n",$x_data,$y_data,0.0
! 1596: }
! 1597: $prod_xy{$index_key} = 0.0;
! 1598: }
! 1599: if(defined $sum_x{$index_key} ) {
! 1600: $sum_x{$index_key} += $x_data;
! 1601: } else {
! 1602: $sum_x{$index_key} = 0;
! 1603: }
! 1604: if(defined $sum_y{$index_key}) {
! 1605: $sum_y{$index_key} += $y_data;
! 1606: } else {
! 1607: $sum_y{$index_key} = 0;
! 1608: }
! 1609: if(defined $sum_x2{$index_key} ) {
! 1610: $sum_x2{$index_key} += ($x_data * $x_data);
! 1611: } else {
! 1612: $sum_x2{$index_key} = 0;
! 1613: }
! 1614: if(defined $sum_y2{$index_key} ) {
! 1615: $sum_y2{$index_key} += ($y_data * $y_data);
! 1616: } else {
! 1617: $sum_y2{$index_key} = 0;
! 1618: }
! 1619: # add one count to valid_count
! 1620: if(defined $valid_cnt{$index_key}) {
! 1621: $valid_cnt{$index_key}++;
! 1622: } else {
! 1623: $valid_cnt{$index_key} = 1;
! 1624: }
! 1625: }
! 1626: }
! 1627: } # end $jj loop
! 1628: } # end $ii loop
! 1629: } # end $line_cnt > 3
! 1630: } # end while <IN>
! 1631: close(IN) || die "Cannot close file $filename!";
! 1632: # print out the correlation matrix
! 1633:
! 1634: print " ";
! 1635: for($ii=1;$ii<=$question_cnt;$ii++) {
! 1636: print " " x 4;
! 1637: printf "%2d", $ii+1;
! 1638: }
! 1639: print "\n";
! 1640: # --------------------------------------
! 1641: for($ii=0;$ii<$question_cnt;$ii++) {
! 1642: printf " %2d:", $ii+1;
! 1643: print " " x ($ii);
! 1644: for($jj=$ii+1;$jj<=$question_cnt;$jj++) {
! 1645: $index_key = "$ii" . "$jj";
! 1646: if( defined $valid_cnt{$index_key}) { ## there are at least one valid data
! 1647: $upper_part = $prod_xy{$index_key} - ( ($sum_x{$index_key} * $sum_y{$index_key}) / $valid_cnt{$index_key} );
! 1648: $lower_part = $sum_x2{$index_key} - ($sum_x{$index_key} * $sum_x{$index_key} / $valid_cnt{$index_key} );
! 1649: $lower_part = $lower_part * ( $sum_y2{$index_key} - ($sum_y{$index_key} * $sum_y{$index_key} / $valid_cnt{$index_key} ));
! 1650: $lower_part = sqrt($lower_part);
! 1651: if ($ii == 3 && $jj==7) {
! 1652: printf "%f %f %f %f",$prod_xy{$index_key},$sum_x{$index_key},$sum_y{$index_key},$valid_cnt{$index_key};
! 1653: }
! 1654: if( $lower_part != 0.0 ) {
! 1655: $ratio = $upper_part / $lower_part;
! 1656: printf " % .2f", $ratio;
! 1657: } else {
! 1658: print " inf ";
! 1659: }
! 1660: } else {
! 1661: print " ----";
! 1662: }
! 1663: }
! 1664: print "\n";
! 1665: }
! 1666: printf "Press RETURN to continue"; $tmp = <>;
! 1667: } else { # file exists!
! 1668: print "FILE: $filename does not exist!\n";
! 1669: print "Press RETURN to continue"; $tmp = <>;
! 1670: }
! 1671: }
! 1672: # -------------------------- Create a file contains all scores ----
! 1673: # it will
! 1674: sub S_CreateScores {
! 1675: local($sfilename)=@_;
! 1676: local($filename);
! 1677: local($c_scores,$c_max_scores,$c_abscent,$c_count,$c_summary);
! 1678: local($q_scores,$q_max_scores,$q_abscent,$q_count,$q_summary);
! 1679: local($e_scores,$e_max_scores,$e_abscent,$e_count,$e_summary);
! 1680: local($s_scores,$s_max_scores,$s_abscent,$s_count,$s_summary);
! 1681: local($o_scores,$o_max_scores,$o_abscent,$o_count,$o_summary);
! 1682: local($c_ratio,$q_ratio,$e_ratio,$s_ratio,$o_ratio);
! 1683: local($m_1,$m_2,$m_3,$f_score);
! 1684: local($m_max1,$m_max2,$m_max3,$f_max);
! 1685: local($mt1_ratio,$mt2_ratio,$mt3_ratio,$f_ratio);
! 1686: local($var_name);
! 1687: local($total_score,$day_str);
! 1688: local($e_entry);
! 1689: local($s_key,%f_entry,$pre_entry,$whole_entry,$tail_entry,$score_str);
! 1690: local($tmp);
! 1691:
! 1692: $day_str = &TimeString;
! 1693:
! 1694: $filename = "$ClassPath" . "/classl";
! 1695:
! 1696: open(CIN, "<$filename") || die "Cannot open file $filename!";
! 1697: while(<CIN>) {
! 1698: chomp();
! 1699: $s_id = substr($_,14,9); $s_id = uc($s_id);
! 1700:
! 1701: # $homework_scores_limit_set comes from capa.config
! 1702: ($c_scores,$c_max_scores,$c_abscent,$c_count,$c_summary) =
! 1703: &S_CollectSetScores($ClassPath,"$s_id",0,$homework_scores_limit_set);
! 1704:
! 1705: $c_ratio = $c_scores/$c_max_scores if $c_max_scores != 0;
! 1706: ## print "$c_scores/$c_max_scores,$c_abscent/$c_count\n";
! 1707:
! 1708: # $quiz_scores_limit_set comes from capa.config
! 1709: ($q_scores,$q_max_scores,$q_abscent,$q_count,$q_summary) =
! 1710: &S_CollectSetScores($QuizPath,"$s_id",0,$quiz_scores_limit_set) if -d "$QuizPath";
! 1711: $q_ratio = $q_scores/$q_max_scores if $q_max_scores != 0;
! 1712: ## print "$q_scores/$q_max_scores,$q_abscent/$q_count\n";
! 1713:
! 1714: # exam has different formula
! 1715:
! 1716: ($m_1,$m_max1,$m_2,$m_max2,$m_3,$m_max3,$f_score,$f_max,$e_count) = S_CollectExamScores($ExamPath,"$s_id") if -d "$ExamPath";
! 1717:
! 1718: # we can evaluate midterm1 when $e_count > 2
! 1719: # the perl code for midterm1 is stored in $P_code{'midterm1'}
! 1720: # FORMULA for exam scores
! 1721: if( $e_count < 1 ) { # 0 set, no extrapolated scores
! 1722: $e_scores = 0;
! 1723: $tail_entry = " --/-- --/-- --/-- --/-- ";
! 1724:
! 1725: } elsif ( ($e_count == 1) || ($e_count == 2) ) {
! 1726: $mt1_ratio = $m_1/$m_max1 if $m_max1 != 0;
! 1727: $e_scores = $mt1_percent * $mt1_ratio + $mt2_percent*$mt1_ratio + $mt3_percent * $mt1_ratio + $final_percent * $mt1_ratio;
! 1728: $e_entry = sprintf " %6.2f/%3d --/-- --/-- --/-- ", $m_1,$m_max1;
! 1729: } elsif ( ($e_count == 3) || ($e_count == 4) ) {
! 1730: $mt1_ratio = $m_1/$m_max1 if $m_max1 != 0;
! 1731: $mt2_ratio = $m_2/$m_max2 if $m_max2 != 0;
! 1732: $e_scores = $mt1_percent * $mt1_ratio + $mt2_percent*$mt2_ratio +
! 1733: (($mt1_percent * $mt1_ratio + $mt2_percent*$mt2_ratio)*0.5) +
! 1734: $final_percent * (($m_1 + $m_2)/($m_max1 + $m_max2));
! 1735: $e_entry = sprintf " %6.2f/%3d %6.2f/%3d --/-- --/-- ", $m_1,$m_max1,$m_2,$m_max2;
! 1736: } elsif ( ($e_count == 5) || ($e_count == 6) ) {
! 1737: $mt1_ratio = $m_1/$m_max1 if $m_max1 != 0;
! 1738: $mt2_ratio = $m_2/$m_max2 if $m_max2 != 0;
! 1739: $mt3_ratio = $m_3/$m_max3 if $m_max3 != 0;
! 1740: $e_scores = $mt1_percent * $mt1_ratio + $mt2_percent*$mt2_ratio + $mt3_percent * $mt3_ratio +
! 1741: $final_percent * (($m_1+$m_2+$m_3)/($m_max1+$m_max2+$m_max3));
! 1742: $e_entry = sprintf " %6.2f/%3d %6.2f/%3d %6.2f/%3d --/-- ", $m_1,$m_max1,$m_2,$m_max2,$m_3,$m_max3;
! 1743: } else { # suppose to be 7
! 1744: $mt1_ratio = $m_1/$m_max1 if $m_max1 != 0;
! 1745: $mt2_ratio = $m_2/$m_max2 if $m_max2 != 0;
! 1746: $mt3_ratio = $m_3/$m_max3 if $m_max3 != 0;
! 1747: $f_ratio = $f_score/$f_max if $f_max != 0;
! 1748: $e_scores = $mt1_percent * $mt1_ratio + $mt2_percent*$mt2_ratio + $mt3_percent * $mt3_ratio + $final_percent * $f_ratio;
! 1749: $e_entry = sprintf " %6.2f/%3d %6.2f/%3d %6.2f/%3d %3d/%3d ",$m_1,$m_max1,$m_2,$m_max2,$m_3,$m_max3,$f_score,$f_max;
! 1750: }
! 1751:
! 1752: # $supp_scores_limit_set comes from capa.config
! 1753: ($s_scores,$s_max_scores,$s_abscent,$s_count,$s_summary) =
! 1754: &S_CollectSetScores($SuppPath,"$s_id",0,$supp_scores_limit_set) if -d "$SuppPath";
! 1755: $s_ratio = $s_scores/$s_max_scores if $s_max_scores != 0;
! 1756: ## print "$s_scores/$s_max_scores,$s_abscent/$s_count\n";
! 1757:
! 1758: # $others_scores_limit_set comes from capa.config
! 1759: ($o_scores,$o_max_scores,$o_abscent,$o_count,$o_summary) =
! 1760: &S_CollectSetScores($OthersPath,"$s_id",0,$others_scores_limit_set) if -d "$OthersPath";
! 1761: $o_ratio = $o_scores/$o_max_scores if $o_max_scores != 0;
! 1762: ## print "$o_scores/$o_max_scores,$o_abscent/$o_count\n";
! 1763:
! 1764:
! 1765: $total_score = $hw_percent*$c_ratio + $qz_percent*$q_ratio + $e_scores;
! 1766:
! 1767: $score_str = sprintf "% 6.2f", $total_score;
! 1768: $s_key = sprintf "%06.2f %s", $total_score,$s_id;
! 1769: # # HW QZ QZ-N SUPP Mid 1 Mid 2 Mid 3 Final Total
! 1770: #
! 1771: # A12345678 123/123 123/123 123/123 123/123 123.45/123 123.45/123 123.45/123 123/123 123.45
! 1772: #
! 1773: # A23546721 335/341 45/ 45 0/ 15 76/ 81 30.00/ 30 28.60/ 30 30.00/ 30 56/ 57 100.39
! 1774: # A23778965 333/341 34/ 45 1/ 15 79/ 81 27.90/ 30 28.60/ 30 28.60/ 30 55/ 57 96.72
! 1775: # A11111111 0/341 0/ 45 14/ 15 0/ 81 0.00/ 30 0.00/ 30 0.00/ 30 0/ 57 0.00
! 1776: # 173533390 0/341 0/ 45 15/ 15 0/ 81 0.00/ 30 0.00/ 30 0.00/ 30 0/ 57 0.00
! 1777:
! 1778: $pre_entry = sprintf "%3d/%3d %3d/%3d %3d/%3d %3d/%3d",
! 1779: $c_scores,$c_max_scores,$q_scores,$q_max_scores,$q_abscent,$q_count,$s_scores,$s_max_scores;
! 1780:
! 1781:
! 1782: $tail_entry = sprintf "%6.2f", $total_score;
! 1783:
! 1784:
! 1785: $whole_entry = "$s_id " . "$pre_entry" . "$e_entry" . "$tail_entry\n";
! 1786:
! 1787: $f_entry{$s_key} = $whole_entry;
! 1788: print " $s_id $score_str \[$pre_entry\]\n";
! 1789: print "\t\t\[$e_entry $tail_entry\]\n";
! 1790: }
! 1791: close(CIN) || die "Cannot close file $filename!";
! 1792: # close the classl file and
! 1793:
! 1794: # open the set score report file
! 1795: if(-f $sfilename) { # if there is already a scores file, move it to something else
! 1796: system("mv $sfilename $sfilename.prior.$day_str");
! 1797: }
! 1798: open(OUT, ">$sfilename") || die "Cannot open file $sfilename!";
! 1799: print OUT "\# HW QZ QZ-N SUPP Mid 1 Mid 2 Mid 3 Final Total\n";
! 1800: foreach $s_key (reverse sort keys %f_entry) {
! 1801: print OUT "$f_entry{$s_key}";
! 1802: }
! 1803: close(OUT) || die "Cannot close file $sfilename!";
! 1804: }
! 1805:
! 1806: #
! 1807: # create all emails in the Mail/ directory
! 1808: # input is the master scores file name
! 1809: sub S_CreateEmails {
! 1810: local($sfilename)=@_;
! 1811: local($efilename);
! 1812: local($s_id);
! 1813: local($var_name,$s_sec,$email);
! 1814: local($q_scores,$q_max_scores,$q_absent,$q_count,$q_summary);
! 1815: local($last_n,$first_n,$first_part,$middle_n);
! 1816: local($day_str,$cat,$tmp);
! 1817:
! 1818: # variable $Email_templateFile comes from capa.config entry email_template_file
! 1819: &ScanMailTemplate("$Email_templateFile");
! 1820:
! 1821: # after scanning the email template file, $P_code{'email_perl'} and $P_code{'template'} are defined
! 1822: # in the code $P_code{'email_perl'}, we need to define
! 1823: # $final_grade and
! 1824: # $category_one_high, $category_one_low, .. comes from capa.config
! 1825: # output $Summary_sentence
! 1826:
! 1827: # in the code $P_code{'template'}
! 1828: $day_str = &TodayString;
! 1829:
! 1830: if(-f $sfilename) {
! 1831: open(SIN, "<$sfilename") || die "Cannot open file $sfilename!";
! 1832: while(<SIN>) {
! 1833: # 1 2 3 4 5 6 7 8 9
! 1834: # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
! 1835: # # HW QZ QZ-N SUPP Mid 1 Mid 2 Mid 3 Final Total
! 1836: # A23546721 335/341 45/ 45 0/ 15 76/ 81 30.00/ 30 28.60/ 30 30.00/ 30 56/ 57 100.39
! 1837: if(! /^\#/) { # non comments line
! 1838: $s_id = substr($_,0,9); $s_id = uc($s_id);
! 1839: $var_name = $Var_name{'Homework_total_score'};
! 1840: ${$var_name} = int( substr($_,10,3) ); # homework total score
! 1841: $var_name = $Var_name{'Homework_total_max'};
! 1842: ${$var_name} = int( substr($_,14,3) ); # max score
! 1843: $var_name = $Var_name{'Quiz_total_score'};
! 1844: ${$var_name} = int( substr($_,18,3) ); # quiz score
! 1845: $var_name = $Var_name{'Quiz_total_max'};
! 1846: ${$var_name} = int( substr($_,22,3) ); # quiz max
! 1847:
! 1848: $var_name = $Var_name{'Quiz_absent'};
! 1849: ${$var_name} = int( substr($_,26,3) ); # quiz absent
! 1850:
! 1851: $var_name = $Var_name{'Quiz_count'};
! 1852: ${$var_name} = int( substr($_,30,3) ); # quiz count
! 1853:
! 1854: # need to take care of '--'
! 1855:
! 1856: $midterm1 = substr($_,42,6);
! 1857: $midterm_max1 = int( substr($_,49,3));
! 1858:
! 1859: $midterm2 = substr($_,53,6);
! 1860: $midterm_max2 = int( substr($_,60,3));
! 1861:
! 1862: $midterm3 = substr($_,64,6);
! 1863: $midterm_max3 = int( substr($_,71,3));
! 1864:
! 1865: $final_exam = substr($_,75,3);
! 1866: $final_exam_max = int( substr($_,79,3));
! 1867:
! 1868: $final_grade = substr($_,85,6); # server as input to $P_code{'email_perl'}
! 1869:
! 1870: $final_grade = $final_grade * 1.0;
! 1871:
! 1872: ## print "PERL: $P_code{'email_perl'}\n";
! 1873: ## print "Press RETURN to continue"; $tmp = <>;
! 1874:
! 1875: ## print "SUMMARY: $Summary_sentence\n";
! 1876: ## print "Press RETURN to continue"; $tmp = <>;
! 1877:
! 1878: # now we know $Exam_sentence and $Summary_sentence
! 1879:
! 1880: # for $P_code{'template'}, we need to find
! 1881: # Global input
! 1882: # $student_name, $ClassName, there is already a $ClassName global variable
! 1883: # ${$Var_name{'Homework_total_score'}} ==> $HWtotal_scp
! 1884: # ${$Var_name{'Homework_total_max'}} ==> $HWtotal_max_scp
! 1885: # ${$Var_name{'Quiz_count'}} ==> $QZcount_scp
! 1886: # ${$Var_name{'Quiz_total_score'}} ==> $QZtotal_scp
! 1887: # ${$Var_name{'Quiz_total_max'}} ==> $QZtotal_max_scp
! 1888:
! 1889: # ${$Var_name{'Quiz_summary_string'}} ==> $QZsummary <-- must read from the qz/records/*.db files
! 1890:
! 1891: # $midterm1, $midterm2, $midterm3 and $final_exam
! 1892: #
! 1893: ## How to allow the format of $student_name customizable from capa.config file?
! 1894: ##
! 1895: ($student_name,$s_sec,$email) = S_Lookup_student_name("$s_id");
! 1896: ($last_n,$first_part) = split(/,/,$student_name);
! 1897: $first_part =~ s/^\s//g;
! 1898: ($first_n,$middle_n) = split(/ /,$first_part);
! 1899: $student_name = "$first_n" . " $last_n";
! 1900:
! 1901: # $quiz_scores_limit_set comes from capa.config
! 1902: ($q_scores,$q_max_scores,$q_absent,$q_count,$q_summary) =
! 1903: &S_CollectSetScores($QuizPath,"$s_id",0,$quiz_scores_limit_set) if -d "$QuizPath";
! 1904: ${$Var_name{'Quiz_summary_string'}} = "$q_summary";
! 1905: ${$Var_name{'Quiz_absent'}} = $q_absent;
! 1906: ${$Var_name{'Quiz_count'}} = $q_count;
! 1907: eval "$P_code{'email_perl'}";
! 1908: if( ($final_grade <= $category_one_high) && ($final_grade >= $category_one_low)) {
! 1909: $cat = 1;
! 1910: } elsif ( ($final_grade <= $category_two_high)&&($final_grade >= $category_two_low) ) {
! 1911:
! 1912: $cat = 2;
! 1913:
! 1914: } elsif ( ($final_grade <= $category_three_high)&&($final_grade >= $category_three_low) ) {
! 1915:
! 1916: $cat = 3;
! 1917:
! 1918: } elsif( ($final_grade <= $category_four_high)&&($final_grade >= $category_four_low) ) {
! 1919:
! 1920: $cat = 4;
! 1921:
! 1922: } else { # not in above category
! 1923:
! 1924: $cat = 5;
! 1925: }
! 1926:
! 1927: $efilename = "$ClassPath" . "/Mail/$s_id.$day_str.$cat";
! 1928:
! 1929: if(-f $efilename) { # remove the file with the same name, no warning!!
! 1930: system("rm $efilename");
! 1931: }
! 1932: open(EOUT,">$efilename") || die "Cannot create file $efilename!";
! 1933: eval "print EOUT \"$P_code{'template'}\" ";
! 1934: close(EOUT) || die "Cannot close file $efilename!";
! 1935:
! 1936: print " $s_id\t$final_grade,\tcategory $cat\n";
! 1937:
! 1938: }
! 1939: }
! 1940: close(SIN) || die "Cannot close file $sfilename!";
! 1941: print "=" x 45 . "\n";
! 1942: print "DONE creating all email files in $ClassPath/Mail/ directory.\n";
! 1943: print "Press RETURN to continue"; $tmp = <>;
! 1944: } else { # the master scores file does not exist
! 1945: print "File $sfilename does not exist!\n";
! 1946: print "Press RETURN to continue"; $tmp = <>;
! 1947: }
! 1948:
! 1949: }
! 1950: # ----------------------------------------------------------------
! 1951: sub ScanMailTemplate {
! 1952: local($filename) = @_;
! 1953: local($input_line);
! 1954: local($tmp);
! 1955:
! 1956:
! 1957: if(-f $filename) {
! 1958: open(IN, "<$filename") || die "Cannot open $filename\n";
! 1959: LINE: while( $input_line = <IN> ) {
! 1960: chomp($input_line);
! 1961: if($input_line =~ m|^//| ) { next LINE; } ## ignore comments
! 1962: if($input_line =~ m|^\#| ) { next LINE; } ## ignore comments
! 1963: if($input_line =~ m|^\s*BEGIN_perl| ) { ## Perl code
! 1964: $P_code{'email_perl'} = &E_CollectPerlCode;
! 1965: ## print "email_perl=$P_code{'email_perl'}";
! 1966: next LINE;
! 1967: }
! 1968: if($input_line =~ m|^\s*BEGIN_template| ) { ## template code
! 1969: $P_code{'template'} = &E_CollectTemplateCode;
! 1970: ## print "template = $P_code{'template'}";
! 1971: next LINE;
! 1972: }
! 1973: next LINE;
! 1974: }
! 1975: close(IN) || die "Cannot close $filename\n";
! 1976:
! 1977: } else {
! 1978: printf "File $filename does not exist!"; $tmp = <>;
! 1979: }
! 1980:
! 1981: }
! 1982:
! 1983: #
! 1984: # Randomly pick a file in Mail/ directory and display
! 1985: # it on screen
! 1986: #
! 1987: sub S_RandomlyPreview {
! 1988: local($filename);
! 1989: local(@all_files);
! 1990: local($upper_bound);
! 1991: local($pick_idx,$pick_filename);
! 1992: local($tmp);
! 1993:
! 1994: opendir(EDIR, "$ClassPath/Mail") || die "cannot opendir $ClassPath/Mail!";
! 1995: @all_files = grep !/^\.\.?$/, readdir EDIR;
! 1996: closedir EDIR;
! 1997: ## srand(time() ^ ($$+( $$ << 15)) );
! 1998:
! 1999: $upper_bound = $#all_files + 1;
! 2000: if( $upper_bound > 0 ) { # something to preview
! 2001: $pick_idx = ((rand $$) * 1000.0) % $upper_bound;
! 2002:
! 2003: # print "PICK: $pick_idx among $upper_bound\n";
! 2004:
! 2005: $pick_filename = $all_files[$pick_idx];
! 2006: print "Preview File: $pick_filename\n";
! 2007: print "Press RETURN to continue"; $tmp = <>; &C_ClearScreen;
! 2008: $filename = "$ClassPath/Mail/$pick_filename";
! 2009: open(IN,"<$filename") || die "Cannot open file $filename!";
! 2010: while(<IN>) {
! 2011: print;
! 2012: }
! 2013: close(IN) || die "cannot close file $filename!";
! 2014: print "Press RETURN to continue"; $tmp = <>;
! 2015: } else {
! 2016: print "No file in directory $ClassPath/Mail\n";
! 2017:
! 2018: print "Press RETURN to continue"; $tmp = <>;
! 2019:
! 2020: }
! 2021:
! 2022: }
! 2023:
! 2024:
! 2025: # The format of a classl file
! 2026: #
! 2027: # 1 2 3 4 5 6 7 8 9 0
! 2028: #0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
! 2029: #PHY 183 001 A23745301 Abraham, Christopher Wil FS96
! 2030: #phy 111 001 A12345678 BUMSTEAD, Blondie blondie4@pilot.msu.edu 12345678
! 2031: #PHY 183 003 A24469315 Costigan, Timothy Patric costiga3@pilot.msu.edu costiga3
! 2032: #PHY 183 002 A25425738 Cacossa, Andrew Vincent cacossaa@pilot.msu.edu cacossaa
! 2033:
! 2034: # lookup the student id supplied in variable $student_id
! 2035: # and return the student name and the e-mail address if available
! 2036: sub S_Lookup_student_name {
! 2037: local($student_id)=@_;
! 2038: local($filename);
! 2039: local($found,$input_line);
! 2040: local($tmp_sn,$student_name);
! 2041: local($len,$s_sec,$email);
! 2042:
! 2043: $student_id = uc($student_id);
! 2044: $filename = $ClassPath . "/classl";
! 2045: open(CIN, "<$filename") || die "Cannot open file $filename!";
! 2046: $found = 0;
! 2047: while( ($input_line = <CIN>) && (! $found) ) {
! 2048: chomp($input_line);
! 2049: $tmp_sn = substr($input_line,14,9); $tmp_sn = uc($tmp_sn);
! 2050: if($tmp_sn =~ /^$student_id/ ) {
! 2051: $found=1;
! 2052: # student name begins at column 24 and has 30 chars max
! 2053: $s_sec = substr($input_line,10,3);
! 2054: $student_name = substr($input_line,24,30);
! 2055: $len = length($input_line);
! 2056: $email = "";
! 2057: if($len > 55 ) {
! 2058: $email = substr($input_line,55,32);
! 2059: $email =~ s/\s+//g;
! 2060: if( $email !~ /\@|\./ ) {
! 2061: $email = "";
! 2062: }
! 2063: }
! 2064: }
! 2065: }
! 2066: close(CIN) || die "Cannot close file $filename!";
! 2067: return ($student_name,$s_sec,$email);
! 2068: }
! 2069:
! 2070: # This routine accepts a string represent an absolute path to a class
! 2071: # it checks to see if
! 2072: # the directory specified by this path did actually exist
! 2073: # the records/ sub-directory did exist
! 2074: # the records/setX.db file exists
! 2075: # the classl file exists
! 2076:
! 2077: sub S_CheckClassPath {
! 2078: local($path)=@_;
! 2079: local($cfullpath,$rfullpath,$sfullpath);
! 2080: local($correct,$cfgfullpath,$cfgutilsfullpath);
! 2081:
! 2082: $correct = 0;
! 2083: if( $path =~ /\/$/ ) {
! 2084: $cfullpath = "$path" . "classl";
! 2085: $rfullpath = "$path" . "records";
! 2086: $sfullpath = "$path" . "records/set$set.db";
! 2087: $cfgfullpath = "$path" . "capa.config";
! 2088: $cfgutilsfullpath = "$path" . "capautils.config";
! 2089: } else {
! 2090: $cfullpath = "$path" . "/classl";
! 2091: $rfullpath = "$path" . "/records";
! 2092: $sfullpath = "$path" . "/records/set$set.db";
! 2093: $cfgfullpath = "$path" . "/capa.config";
! 2094: $cfgutilsfullpath = "$path" . "/capautils.config";
! 2095: }
! 2096: if( -d $path ) {
! 2097: if( -d $rfullpath ) {
! 2098: if(-f $cfgfullpath ) {
! 2099: if(-f $cfgutilsfullpath ) {
! 2100: $correct = 1;
! 2101: } else {
! 2102: print "File [$cfgutilsfullpath] does not exist!\n";
! 2103: }
! 2104: } else {
! 2105: print "File [$cfgfullpath] does not exist!\n";
! 2106: }
! 2107: } else {
! 2108: print "Directory [$rfullpath] does not exist!\n";
! 2109: }
! 2110: } else {
! 2111: print "Directory [$path] does not exist!\n";
! 2112: }
! 2113: return ($correct);
! 2114: }
! 2115:
! 2116: ##
! 2117: # display score file according to the order specified
! 2118: # by $key_str and the direction in $dir
! 2119: # $dir = 1 means ascending
! 2120: # 2 means descending
! 2121: #
! 2122: sub S_DisplayScoreFile {
! 2123: local($key_str,$dir,$sfilename)=@_;
! 2124: local(@a_keyidx);
! 2125: local($key_seq);
! 2126: local($s_id,$final_grade,$s_name,$s_sec,$s_email);
! 2127: local($sort_key,$s_display_name,$first_n,$first_part,$middle_n,$last_n);
! 2128: local(%sf_entry);
! 2129: local($line_cnt,$line_total,$len,$pad_len);
! 2130: local($tmp);
! 2131:
! 2132: $key_str =~ s/,//g;
! 2133: $key_str =~ s/1/\$final_grade/g;
! 2134: $key_str =~ s/2/\$s_id/g;
! 2135: if( $key_str =~ /3/ ) {
! 2136: $key_str =~ s/3/\$s_name/g;
! 2137: }
! 2138: if( $key_str =~ /4/ ) {
! 2139: $key_str =~ s/4/\$s_sec/g;
! 2140: }
! 2141: $key_seq = '"' . "$key_str" . '"';
! 2142:
! 2143: if(-f $sfilename) {
! 2144: open(SIN, "<$sfilename") || die "Cannot open file $sfilename!";
! 2145: $line_cnt = 0;
! 2146: while(<SIN>) {
! 2147: if(! /^\#/) { # non comments line
! 2148: chomp();
! 2149: $line_cnt++;
! 2150: $s_id = substr($_,0,9); $s_id = uc($s_id);
! 2151: $final_grade = substr($_,85,6); #
! 2152:
! 2153: $whole_entry = $_;
! 2154: ($s_name,$s_sec,$s_email) = S_Lookup_student_name("$s_id");
! 2155: # evaluate the code to a real key
! 2156: $sort_key = eval $key_seq;
! 2157:
! 2158: ($last_n,$first_part) = split(/,/,$s_name);
! 2159: $last_n = uc($last_n);
! 2160: $first_part =~ s/^\s//g;
! 2161: ($first_n,$middle_n) = split(/ /,$first_part);
! 2162: $s_display_name = "$last_n" . ", $first_n";
! 2163: $len = length($s_display_name);
! 2164: if( $len < 25 ) {
! 2165: $pad_len = 25 - $len;
! 2166: $s_display_name = "$s_display_name" . " " x $pad_len;
! 2167: } else {
! 2168: $s_display_name = substr($s_display_name,0,25);
! 2169: }
! 2170: $sf_entry{"$sort_key"} = "$s_display_name $s_sec $whole_entry";
! 2171: ### print "KEY:[$sort_key]:$whole_entry\n";
! 2172: } # end of if not comments
! 2173: } # end while <SIN>
! 2174: close(SIN) || die "Cannot close file $sfilename!";
! 2175: $line_total = $line_cnt; $line_cnt = 0;
! 2176: if($dir == 1 ) {
! 2177: foreach $sort_key (sort keys %sf_entry) {
! 2178: $line_cnt++;
! 2179: print $sf_entry{"$sort_key"} . "\n";
! 2180: if( ($line_cnt % $display_score_row_limit) == 0 ) { # $display_score_row_limit from capa.config
! 2181: print " --$line_cnt/$line_total-- Press RETURN to continue"; $tmp = <>;
! 2182: }
! 2183: }
! 2184: } else {
! 2185: foreach $sort_key (reverse sort keys %sf_entry) {
! 2186: $line_cnt++;
! 2187: print $sf_entry{"$sort_key"} . "\n";
! 2188: if( ($line_cnt % $display_score_row_limit) == 0 ) {
! 2189: print " --$line_cnt/$line_total-- Press RETURN to continue"; $tmp = <>;
! 2190: }
! 2191: }
! 2192: }
! 2193: } else {
! 2194: print "File [$sfilename] does not exist!";
! 2195: }
! 2196:
! 2197: }
! 2198:
! 2199: ##
! 2200: ## Input: file name to be printed through lpr command
! 2201: ##
! 2202: ##
! 2203: sub S_LPRFile {
! 2204: local($file)=@_;
! 2205: local($go_on)=0;
! 2206: local($select);
! 2207: local($printer_selected);
! 2208: local($emp);
! 2209: local($cmd);
! 2210: local($PS_file);
! 2211:
! 2212: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2213: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2214: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2215:
! 2216: if( $go_on ) { # run lpr -P.... on the .ps file
! 2217: $select = C_MultipleChoice(4,10,$DialogWidth," Printers Available ",
! 2218: "Printer Name",@Printers);
! 2219: $Printer_selected = $Printers[$select-1];
! 2220:
! 2221: $go_on = 0;
! 2222: while( ! $go_on ) {
! 2223: print "Enter 1 for one sided or 2 for two sided printing (RETURN = 1 sided): ";
! 2224: $tmp=<>;
! 2225: if( ($tmp == 1) || ($tmp == 2) || ($tmp eq "\n") ) {
! 2226: $tmp = 1 if $tmp eq "\n";
! 2227: $go_on = 1;
! 2228: }
! 2229: }
! 2230: if( $tmp == 1 ) {
! 2231: $LpronesidedCMD =~ s/\$Printer_selected/$Printer_selected/e;
! 2232: $cmd = "$LpronesidedCMD $file";
! 2233: } else { # should be 2
! 2234: $PS_file = $file;
! 2235: print "$LprtwosidedCMD\n";
! 2236: $LprtwosidedCMD =~ s/\$Printer_selected/$Printer_selected/e;
! 2237: $LprtwosidedCMD =~ s/\$PS_file/$PS_file/e;
! 2238: $cmd = "$LprtwosidedCMD";
! 2239: }
! 2240: $go_on = 0;
! 2241: print "=" x 70 . "\n";
! 2242: print "CMD: $cmd\n";
! 2243: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2244: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2245: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2246: if($go_on) {
! 2247: open(IN,"$cmd|");
! 2248: while($input_line = <IN>) {
! 2249: print "$input_line";
! 2250: }
! 2251: close(IN);
! 2252: print "=" x 70 . "\n";
! 2253: print " Your job has been sent to the print spooler. Press RETURN to continue"; $tmp = <>;
! 2254: }
! 2255: }
! 2256: }
! 2257:
! 2258:
! 2259:
! 2260: # <========================= Main program =======================>
! 2261:
! 2262: Getopts('c:s');
! 2263:
! 2264: if (! $opt_c) { ## class path option
! 2265: print "USAGE: capatools.pl -c Full_path_to_class\n";
! 2266: $ClassPath = &S_Enterpath;
! 2267: } else { # need to check the path entered by option -c
! 2268: if( S_CheckClassPath("$opt_c") ) {
! 2269: $ClassPath = $opt_c;
! 2270: if( $opt_s ) {
! 2271: S_ReadCAPAconfig($ClassPath);
! 2272: S_CreateScores("$Master_scoresFile");
! 2273: # print "run score report in silent background\n";
! 2274: # print "The $Master_scoresFile\n";
! 2275:
! 2276: exit (1);
! 2277: }
! 2278: } else {
! 2279: $ClassPath = &S_Enterpath;
! 2280: }
! 2281: }
! 2282:
! 2283: $DialogWidth = 48;
! 2284: $Quit = 0;
! 2285:
! 2286:
! 2287: $len = length($ClassPath);
! 2288: if( $len > ($DialogWidth-6) ) { ## class path too long, display the last portion instead
! 2289: $offset = $len - $DialogWidth +6;
! 2290: $DisplayPath = "-..." . substr($ClassPath, $offset,$DialogWidth-6);
! 2291: } else {
! 2292: $DisplayPath = $ClassPath;
! 2293: }
! 2294:
! 2295: S_ReadCAPAconfig($ClassPath);
! 2296:
! 2297: while(! $Quit ) {
! 2298: $What = C_MultipleChoice(1,8,$DialogWidth," Welcome to CAPA Utilities Ver 1.1 ",
! 2299: "$DisplayPath",@Main_menu);
! 2300:
! 2301: if( $What == 1 ) { # change class path
! 2302: $ClassPath = &S_Enterpath;
! 2303: $len = length($ClassPath);
! 2304: if( $len > ($DialogWidth-6) ) {
! 2305: $offset = $len - $DialogWidth +6;
! 2306: $DisplayPath = "-..." . substr($ClassPath, $offset,$DialogWidth-6);
! 2307: } else {
! 2308: $DisplayPath = $ClassPath;
! 2309: }
! 2310: S_ReadCAPAconfig($ClassPath);
! 2311: } elsif ($What == 2 ) { # run capastat.pl
! 2312: $Set = &S_InputSet;
! 2313: $Sfullpath = $ClassPath . "/records/set" . "$Set" . ".db";
! 2314: ## print "Running capastat.pl on $Sfullpath\n";
! 2315: ($Q_cnt,$L_cnt) = &S_ScanSetDB($Sfullpath);
! 2316: Percentage_Scores($Set,$L_cnt);
! 2317: S_Average($Q_cnt,$L_cnt);
! 2318:
! 2319: ## Large_Tries($opt_t,$opt_n,$Q_cnt,$L_cnt);
! 2320: } elsif ($What == 3 ) { # log analysis on S, U,
! 2321: $Set = &S_InputSet;
! 2322:
! 2323: $Lfullpath = $ClassPath . "/records/log" . "$Set" . ".db";
! 2324: if(-f $Lfullpath) {
! 2325: print "Log analysis for telnet session log$Set.db\n";
! 2326: print " This may take a while to calculate, please wait ...\n";
! 2327: ($Y_l,$N_l,$S_l,$U_l,$u_l) = S_ScanLogDB($Lfullpath);
! 2328: }
! 2329: $Wfullpath = $ClassPath . "/records/weblog" . "$Set" . ".db";
! 2330: if(-f $Wfullpath ) {
! 2331: print "=" x 79 . "\n";
! 2332: print "Log analysis for web session weblog$Set.db\n";
! 2333: print " This may take a while to calculate, please wait ...\n";
! 2334: ($Y_w,$N_w,$S_w,$U_w,$u_w) = S_ScanLogDB($Wfullpath);
! 2335: }
! 2336: $Telnet_total = $Y_l+$N_l+$S_l+$U_l+$u_l;
! 2337: $Web_total = $Y_w+$N_w+$S_w+$U_w+$u_w;
! 2338:
! 2339: print "============== SUMMARY ====================\n";
! 2340: print " #Y #N #S #U #u Total\n";
! 2341: printf "telnet: %6d %6d %6d %6d %6d %6d\n", $Y_l, $N_l, $S_l, $U_l, $u_l,$Telnet_total;
! 2342: printf " web: %6d %6d %6d %6d %6d %6d\n", $Y_w, $N_w, $S_w, $U_w, $u_w,$Web_total;
! 2343: $Y_sum = $Y_l + $Y_w;
! 2344: $Ratio_Y = 100.0 * ($Y_w / $Y_sum) if $Y_sum > 0;
! 2345: $N_sum = $N_l + $N_w;
! 2346: $Ratio_N = 100.0 * ($N_w / $N_sum) if $N_sum > 0;
! 2347: $S_sum = $S_l + $S_w;
! 2348: $Ratio_S = 100.0 * ($S_w / $S_sum) if $S_sum > 0;
! 2349: $U_sum = $U_l + $U_w;
! 2350: $Ratio_U = 100.0 * ($U_w / $U_sum) if $U_sum > 0;
! 2351: $u_sum = $u_l + $u_w;
! 2352: $Ratio_u = 100.0 * ($u_w / $u_sum) if $u_sum > 0;
! 2353: $overall_entries = $Telnet_total+$Web_total;
! 2354: $Ratio_web = 100.0*($Web_total/$overall_entries) if $overall_entries > 0;
! 2355: printf " %%web: % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f % 6.1f\n",
! 2356: $Ratio_Y, $Ratio_N, $Ratio_S, $Ratio_U, $Ratio_u, $Ratio_web;
! 2357: printf "Press RETURN to continue"; $tmp = <>;
! 2358:
! 2359: } elsif ($What == 4 ) { # Student course profile
! 2360: # select either use student name or student number
! 2361: # if there are more than two students, display them in a table to select
! 2362: # by the user
! 2363: # use student id to find the scores
! 2364: # display set scores in each class, regular class goes first.
! 2365: # S_InputStudent;
! 2366: ($s_id,$s_nm) = S_InputStudent($ClassPath);
! 2367: if($s_id ne "" ) {
! 2368: print "$s_nm\n";
! 2369: &S_CollectSetScores($ClassPath,"$s_id",1,$homework_scores_limit_set);
! 2370: &S_CollectSetScores($QuizPath,"$s_id",1,$quiz_scores_limit_set) if -d "$QuizPath";
! 2371: &S_CollectSetScores($ExamPath,"$s_id",1,$exam_scores_limit_set) if -d "$ExamPath";
! 2372: &S_CollectSetScores($SuppPath,"$s_id",1,$supp_scores_limit_set) if -d "$SuppPath";
! 2373: &S_CollectSetScores($OthersPath,"$s_id",1,$others_scores_limit_set) if -d "$OthersPath";
! 2374:
! 2375:
! 2376: print "\nEnter Y or <RETURN> for Login analysis (may take a while)\n";
! 2377: print "Enter N => return to main menu: ";
! 2378: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2379: $go_on = 0;
! 2380: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2381:
! 2382: if($go_on) {
! 2383: # $homework_scores_limit_set comes from capa.config
! 2384: &S_LoginAnalysis($ClassPath,"$s_id",$homework_scores_limit_set);
! 2385: &S_StudentSetAnalysis($ClassPath,"$s_id",$homework_scores_limit_set);
! 2386: }
! 2387:
! 2388: }
! 2389: } elsif ($What == 5 ) { # CAPA IDs for one student
! 2390: ($s_id,$s_nm) = S_InputStudent($ClassPath);
! 2391: if($s_id ne "" ) {
! 2392: $go_on = 0;
! 2393: print "$s_nm, $Allcapaid\n";
! 2394: ($S_from, $S_to) = S_EnterSets;
! 2395:
! 2396: print "\nCMD: $AllcapaidCMD -i -stu $s_id -s $S_from -e $S_to\n";
! 2397: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2398: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2399: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2400: if( $go_on ) {
! 2401: open(IN,"$AllcapaidCMD -i -stu $s_id -s $S_from -e $S_to -c $ClassPath|");
! 2402: while($input_line = <IN>) {
! 2403: print "$input_line";
! 2404: }
! 2405: close(IN);
! 2406: printf "Press RETURN to continue"; $tmp = <>;
! 2407: }
! 2408: }
! 2409: } elsif ($What == 6 ) { # All CAPA IDs
! 2410: $go_on = 0;
! 2411: ($S_from, $S_to) = S_EnterSets;
! 2412: print "\nCMD: $AllcapaidCMD -s $S_from -e $S_to\n";
! 2413: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2414: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2415: $go_on = 1 if $tmp =~ /^Y/ || $tmp eq "\n";
! 2416: if( $go_on ) {
! 2417: open(IN,"$AllcapaidCMD -s $S_from -e $S_to -c $ClassPath|");
! 2418: while($input_line = <IN>) {
! 2419: print "$input_line";
! 2420: }
! 2421: close(IN);
! 2422: print "Press RETURN to continue"; $tmp = <>;
! 2423: }
! 2424:
! 2425: } elsif ($What == 7 ) { # Item analysis
! 2426: $u_path = C_MultipleChoice(4,10,$DialogWidth,"Select a Class path","",@MainPath);
! 2427:
! 2428: $Set = &S_InputSet;
! 2429: print "Item analysis for $MainPath[$u_path-1], Set $Set\n";
! 2430: print "This may take a while to calculate, please wait ...\n";
! 2431: S_ItemAnalysis($MainPath[$u_path-1],$Set);
! 2432: } elsif ($What == 8 ) { # Correlation chart
! 2433: ## TO DO:
! 2434: ## Let user specify how many categories to calculate correlation
! 2435: ## For each category, the user can specify problem numbers to
! 2436: ## be in that category
! 2437: ## Then, the correlations between each category is calculated
! 2438: ##
! 2439: $u_path = C_MultipleChoice(4,10,$DialogWidth,"Select a Class path","",@MainPath);
! 2440: $Set = &S_InputSet;
! 2441: print "Correlation calculation for $MainPath[$u_path-1], Set $Set\n";
! 2442: print "This may take a while to calculate, please wait ...\n";
! 2443: S_SetCorrelationStatistics($MainPath[$u_path-1],$Set);
! 2444: } elsif ($What == 9 ) { # E-Mail
! 2445: $done_email = 0;
! 2446: while(! $done_email ) {
! 2447: $select = C_MultipleChoice(2,10,$DialogWidth+15," CAPA E-mail facilities ",
! 2448: "$DisplayPath",@Email_menu);
! 2449: if($select == 1 ) { # Create scores file
! 2450: # the variable $Master_scoresFile comes from capa.config entry master_scores_file = ...
! 2451: print "Create a file containing scores of all students:\n";
! 2452: print " $Master_scoresFile\n";
! 2453: print "This may take a while to complete, please wait ...\n";
! 2454: S_CreateScores("$Master_scoresFile");
! 2455: } elsif ($select == 2 ) { # create all e-mail files in Mail/ dir
! 2456: print "Create e-mail files in $ClassPath/Mail/ directory\n";
! 2457: print " based on scores file $Master_scoresFile\n";
! 2458: print "This action will REPLACE the original file(s) in the Mail/ directory!\n";
! 2459: $go_on = 0;
! 2460: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2461: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2462: $go_on = 1 if $tmp =~ /^Y/ || $tmp eq "\n";
! 2463: if( $go_on ) {
! 2464: print "This may take a while to complete, please wait ...\n";
! 2465:
! 2466: S_CreateEmails("$Master_scoresFile");
! 2467: }
! 2468: } elsif ($select == 3 ) { # Preview e-mail
! 2469: # randomly pick a student
! 2470: #
! 2471: &S_RandomlyPreview;
! 2472:
! 2473: } elsif ($select == 4 ) { # Send e-mail to a group of students
! 2474: $entered_cat = &S_EnterCategory;
! 2475:
! 2476: $go_on = 0;
! 2477: print "Entered category: $entered_cat\n";
! 2478: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2479: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2480: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2481:
! 2482: if( $go_on ) {
! 2483: S_MailtoCategory($entered_cat);
! 2484: }
! 2485:
! 2486:
! 2487: # 1. Whole class
! 2488: # 2. Category ---> specify 1, 2, 3, or 4
! 2489: } else { # 4. Cancel
! 2490: $done_email = 1;
! 2491: }
! 2492: }
! 2493: } elsif ($What == 10 ) { # Print one assignment for a student
! 2494: ($s_id,$s_nm) = S_InputStudent($ClassPath);
! 2495: if($s_id ne "" ) { # non-empty student id
! 2496: $s_id = uc($s_id); # uppercase
! 2497:
! 2498: ## $Set = &S_InputSet;
! 2499: ($From_set,$To_set) = &S_EnterSets;
! 2500: print "Printing Set(s) $From_set to $To_set for STUDENT: $s_nm\n";
! 2501: $go_on = 0;
! 2502: print "\nEnter Y or <RETURN> to continue or N to cancel the operation: ";
! 2503: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2504: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2505:
! 2506: if($go_on) {
! 2507: $go_on = 0;
! 2508: print "CMD: $QzparseCMD -c $ClassPath -set $From_set:$To_set -stu $s_id\n";
! 2509: open(IN,"$QzparseCMD -c $ClassPath -set $From_set:$To_set -stu $s_id|");
! 2510: while($input_line = <IN>) {
! 2511: print "$input_line";
! 2512: }
! 2513: close(IN);
! 2514: print "=" x 70 . "\n";
! 2515: $tex_file = "$ClassPath" . "/TeX/" . "$s_id" . ".tex";
! 2516: print "CMD: $LatexCMD $tex_file\n";
! 2517: print "Enter Y or <RETURN> to continue or N to cancel the operation: ";
! 2518: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2519: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2520:
! 2521: }
! 2522: # run qzparse on the student and the set
! 2523: # qzparse -c $path -set $set -stu $s_id
! 2524: if( $go_on ) { # run latex on the .tex file, latex will create a .dvi file in cwd()
! 2525: $dir = cwd();
! 2526: $go_on = 0;
! 2527:
! 2528: open(IN,"$LatexCMD $tex_file|");
! 2529: while($input_line = <IN>) {
! 2530: print "$input_line";
! 2531: }
! 2532: close(IN);
! 2533: $cwd_dvi_file = "$dir/" . "$s_id" . ".dvi";
! 2534: $dvi_file = "$ClassPath" . "/TeX/" . "$s_id" . ".dvi";
! 2535: $cmd = "mv $cwd_dvi_file $dvi_file";
! 2536: system($cmd);
! 2537: print "=" x 70 . "\n";
! 2538: $ps_file = "$ClassPath" . "/TeX/" . "$s_id" . ".ps";
! 2539: print "CMD: $DvipsCMD $dvi_file -o $ps_file\n";
! 2540: print "\nEnter Y or <RETURN> to continue or N to cancel the operation: ";
! 2541: $tmp=<>; $tmp =~ tr/A-Z/a-z/;
! 2542: $go_on = 1 if $tmp =~ /^y/ || $tmp eq "\n";
! 2543: }
! 2544: if( $go_on ) { # run dvips on the .dvi file
! 2545:
! 2546:
! 2547: open(IN,"$DvipsCMD $dvi_file -o $ps_file|");
! 2548: while($input_line = <IN>) {
! 2549: print "$input_line";
! 2550: }
! 2551: close(IN);
! 2552: print "=" x 70 . "\n";
! 2553:
! 2554: S_LPRFile($ps_file);
! 2555:
! 2556: }
! 2557: }
! 2558:
! 2559: } elsif ($What == 11 ) { # view score file
! 2560: $entered_key = S_EnterSortKey;
! 2561:
! 2562: $display_key = $entered_key;
! 2563: $display_key =~ s/,/, /g;
! 2564: $display_key =~ s/1/Grade/g;
! 2565: $display_key =~ s/2/Student number/g;
! 2566: $display_key =~ s/3/Student name/g;
! 2567: $display_key =~ s/4/Section/g;
! 2568: print "Entered sorting key: $display_key\n";
! 2569: $go_on = 0;
! 2570: while(! $go_on) {
! 2571: print "Enter 1 for ascending or 2 for decending order (RETURN = 1 ascending): ";
! 2572: $tmp=<>;
! 2573: if( ($tmp == 1) || ($tmp == 2) || ($tmp eq "\n") ) {
! 2574: $tmp = 1 if $tmp eq "\n";
! 2575: $go_on = 1;
! 2576: }
! 2577: }
! 2578:
! 2579: S_DisplayScoreFile($entered_key,$tmp,$Master_scoresFile);
! 2580: print "Finish displaying score file. Press RETURN to continue"; $tmp = <>;
! 2581: } elsif ($What == 12 ) { # list student responses
! 2582: ($s_id,$s_nm) = S_InputStudent($ClassPath);
! 2583: if($s_id ne "" ) {
! 2584: $go_on = 0;
! 2585: print "$s_nm, grepping submissions\n";
! 2586: ($S_from, $S_to) = S_EnterSets;
! 2587: for( $i=$S_from;$i<=$S_to;$i++) {
! 2588: print "Telnet Submissions for $s_nm for set $i\n";
! 2589: open(IN,"grep -i $s_id $ClassPath/records/submissions$i.db |");
! 2590: while($input_line = <IN>) {
! 2591: print "$input_line";
! 2592: }
! 2593: close(IN);
! 2594: printf "Press RETURN to continue"; $tmp = <>;
! 2595: print "WWW Submissions for $s_nm for set $i\n";
! 2596: open(IN,"grep -i $s_id $ClassPath/records/websubmissions$i.db|");
! 2597: while($input_line = <IN>) {
! 2598: print "$input_line";
! 2599: }
! 2600: close(IN);
! 2601: printf "Press RETURN to continue"; $tmp = <>;
! 2602: }
! 2603: }
! 2604: } elsif ($What == 13 ) { # quit
! 2605: $Quit = 1;
! 2606: }
! 2607: }
! 2608:
! 2609:
! 2610:
! 2611:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>