File:  [LON-CAPA] / loncom / interface / statistics / lonproblemanalysis.pm
Revision 1.12: download - view: text, annotated - select for diffs
Fri Nov 22 03:56:05 2002 UTC (21 years, 7 months ago) by minaeibi
Branches: MAIN
CVS tags: HEAD
continue to fix bug #939

    1: # The LearningOnline Network with CAPA
    2: # (Publication Handler
    3: #
    4: # $Id: lonproblemanalysis.pm,v 1.12 2002/11/22 03:56:05 minaeibi Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: # (Navigate problems for statistical reports
   29: # YEAR=2002
   30: # 5/12,7/26,9/7,11/22 Behrouz Minaei
   31: #
   32: ###
   33: 
   34: package Apache::lonproblemanalysis;
   35: 
   36: use strict;
   37: use Apache::lonnet();
   38: use Apache::lonhtmlcommon();
   39: use GDBM_File;
   40: 
   41: my $jr;
   42: 
   43: sub BuildProblemAnalysisPage {
   44:     my ($cacheDB, $r)=@_;
   45: 
   46:     my %cache;
   47:     unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
   48:         $r->print('Unable to tie database.');
   49:         return;
   50:     }
   51: 
   52:     my $Ptr = '';
   53:     $Ptr .= '<table border="0"><tbody>';
   54:     $Ptr .= '<tr><td align="right"><b>Select Sections</b>';
   55:     $Ptr .= '</td>'."\n";
   56:     $Ptr .= '<td align="left">'."\n";
   57:     my @sectionsSelected = split(':',$cache{'sectionsSelected'});
   58:     my @sections = split(':',$cache{'sectionList'});
   59:     $Ptr .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections,
   60:                                                           \@sectionsSelected,
   61:                                                           'Statistics');
   62:     $Ptr .= '</td></tr>'."\n";
   63:     $Ptr .= '<tr><td align="right"><b>Intervals</b></td>'."\n";
   64:     $Ptr .= '<td align="left">';
   65:     $Ptr .= &IntervalOptions($cache{'Interval'});
   66:     $Ptr .= '</td></tr></table><br>';
   67:     $r->print($Ptr);
   68:     $r->rflush();
   69:     $r->print(&OptionResponseTable($cache{'OptionResponses'}, \%cache, $r));
   70: 
   71:     untie(%cache);
   72: 
   73:     return;
   74: }
   75: 
   76: sub BuildAnalyzePage {
   77:     my ($cacheDB, $students, $courseID,$r)=@_;
   78: 
   79:     $jr = $r;
   80:     my $c = $r->connection;
   81: 
   82:     my $Str = '</form>';
   83:     my %cache;
   84: 
   85:     unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
   86:         $Str .= 'Unable to tie database.';
   87:         $r->print($Str);
   88:         return;
   89:     }
   90: 
   91:     # Remove students who don't have the proper section.
   92:     my @sectionsSelected = split(':',$cache{'sectionsSelected'});
   93:     for(my $studentIndex=((scalar @$students)-1); $studentIndex>=0;
   94:         $studentIndex--) {
   95:         my $value = $cache{$students->[$studentIndex].':section'};
   96:         my $found = 0;
   97:         foreach (@sectionsSelected) {
   98:             if($_ eq 'none') {
   99:                 if($value eq '' || !defined($value) || $value eq ' ') {
  100:                     $found = 1;
  101:                     last;
  102:                 }
  103:             } else {
  104:                 if($value eq $_) {
  105:                     $found = 1;
  106:                     last;
  107:                 }
  108:             }
  109:         }
  110:         if($found == 0) {
  111:             splice(@$students, $studentIndex, 1);
  112:         }
  113:     }
  114:     unless(untie(%cache)) {
  115:         $r->print('Can not untie hash.');
  116:         $r->rflush();
  117:     }
  118: 
  119:     my $error =
  120:         &Apache::loncoursedata::DownloadStudentCourseDataSeparate($students,
  121:                                                                   'true',
  122:                                                                   $cacheDB,
  123:                                                                   'true',
  124:                                                                   'true',
  125:                                                                   $courseID,
  126:                                                                   $r, $c);
  127:     if($error ne 'OK') {
  128:         $r->print($error.'<br>Error downloading course data<br>');
  129:         return;
  130:     }
  131: 
  132: 
  133:     unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
  134:         $Str .= 'Unable to tie database.';
  135:         $r->print($Str);
  136:         return;
  137:     }
  138: 
  139:     my ($problemId, $part, $responseId)=split(':',$cache{'AnalyzeInfo'});
  140:     my $uri      = $cache{$problemId.':source'};
  141:     my $problem  = $cache{$problemId.':problem'};
  142:     my $title    = $cache{$problemId.':title'};
  143:     my $interval = $cache{'Interval'};
  144: 
  145:     my %ConceptData;
  146:     $ConceptData{"Interval"} = $interval;
  147: 
  148:     #Initialize the option response true answers
  149:     my ($analyzeData) = &InitAnalysis($uri, $part, $responseId, $problem,
  150:                                       $students->[0], $courseID);
  151:     if(defined($analyzeData->{'error'})) {
  152:         $Str .= $analyzeData->{'error'}.'<br>Incorrect part requested.<br>';
  153:         $r->print($Str);
  154:         return;
  155:     }
  156: 
  157:     $r->print($Str);
  158:     $Str = '';
  159:     if($c->aborted()) {  untie(%cache); return; }
  160: 
  161:     #compute the intervals
  162:     &Interval($part, $problem, $interval, $analyzeData->{'concepts'},
  163:               \%ConceptData);
  164: 
  165:     $title =~ s/\ /"_"/eg;
  166:     $Str .= '<br><b>'.$uri.'</b>';
  167: 
  168:     $r->print($Str);
  169:     $Str = '';
  170:     if($c->aborted()) {  untie(%cache); return; }
  171: 
  172:     #Java script Progress window
  173:     for(my $index=0; $index<(scalar @$students); $index++) {
  174:         if($c->aborted()) {  untie(%cache); return; }
  175: 	&OpStatus($problemId, $students->[$index], \%ConceptData,
  176:                   $analyzeData->{'foil_to_concept'}, $analyzeData, 
  177: 		  \%cache, $courseID);
  178:     }
  179: 
  180:     $Str .= '<br>';
  181:     for (my $k=0; $k<$interval; $k++ ) {
  182:         if($c->aborted()) {  untie(%cache); return $Str; }
  183: 	$Str .= &DrawGraph($k, $title, $analyzeData->{'concepts'},
  184:                            \%ConceptData);
  185:         $r->print($Str);
  186:         $Str = '';
  187:     }
  188:     for (my $k=0; $k<$interval; $k++ ) {
  189:         if($c->aborted()) {  untie(%cache); return $Str; }
  190: 	$Str .= &DrawTable($k, $analyzeData->{'concepts'}, \%ConceptData);
  191:         $r->print($Str);
  192:         $Str = '';
  193:     }
  194:     my $Answ=&Apache::lonnet::ssi($uri);
  195:     $Str .= '<br><b>Here you can see the Problem:</b><br>'.$Answ;
  196:     $Str .= '<form>';
  197:     $r->print($Str);
  198: 
  199:     untie(%cache);
  200: 
  201:     return;
  202: }
  203: 
  204: #---- Problem Analysis Web Page ----------------------------------------------
  205: 
  206: sub IntervalOptions {
  207:     my ($selectedInterval)=@_;
  208: 
  209:     my $interval = 1;
  210:     for(my $n=1; $n<=7; $n++) {
  211:         if($selectedInterval == $n) {
  212:             $interval = $n;
  213:         }
  214:     }
  215: 
  216:     my $Ptr = '<select name="Interval">'."\n";
  217:     for(my $n=1; $n<=7;$ n++) {
  218: 	$Ptr .= '<option';
  219:         if($interval == $n) {
  220:             $Ptr .= ' selected';
  221:         }
  222: 	$Ptr .= '>'.$n."</option>"."\n";
  223:     }
  224:     $Ptr .= '</select>'."\n";
  225: 
  226:     return $Ptr;
  227: }
  228: 
  229: sub OptionResponseTable {
  230:     my ($optionResponses,$cache,$r)=@_;
  231: 
  232:     my @optionResponses=split(':::', $optionResponses);
  233:     my %partCount;
  234:     my %sequences;
  235:     my @orderedSequences=();
  236:     foreach(@optionResponses) {
  237:         my ($sequence, $problemId, $part, undef)=split(':',$_);
  238:         $partCount{$problemId.':'.$part}++;
  239:         if(!defined($sequences{$sequence})) {
  240:             push(@orderedSequences, $sequence);
  241:             $sequences{$sequence} = $_;
  242:         } else {
  243:             $sequences{$sequence} .= ':::'.$_;
  244:         }
  245:     }
  246: 
  247:     my $Str = '';
  248: 
  249:     foreach my $sequence (@orderedSequences) {
  250:         my @optionProblems = split(':::', $sequences{$sequence});
  251: 
  252:         $Str .= '<b>'.$cache->{$sequence.':title'}.'</b>'."\n";
  253:         $Str .= "<table border=2><tr><th> \# </th><th> Problem Title </th>";
  254:         $Str .= '<th> Resource </th><th> Analysis  </th></tr>'."\n";
  255: 
  256:         my $count = 1;
  257:         foreach(@optionProblems) {
  258:             my (undef, $problemId, $part, $response)=
  259:                 split(':',$optionProblems[$count-1]);
  260: #                split(':',$sequences{$sequence});
  261:             my $uri = $cache->{$problemId.':source'};
  262:             my $title = $cache->{$problemId.':title'};
  263: 
  264:             my $Temp = '<a href="'.$uri.'" target="_blank">'.$title.'</a>';
  265:             $Str .= '<tr>';
  266:             $Str .= '<td> '.$count.' </td>';
  267:             $Str .= '<td bgcolor="#DDFFDD">'.$Temp.'</td>';
  268:             $Str .= '<td bgcolor="#EEFFCC">'.$uri.'</td>';
  269:             if($partCount{$problemId.':'.$part} < 2) {
  270:                 $Str .= '<td><input type="submit" name="Analyze:::';
  271:                 $Str .= $problemId.':'.$part.'" value="';
  272:                 $Str .= 'Part '.$part;
  273:                 $Str .= '" /></td></tr>'."\n";
  274:             } else {
  275:                 my $value = $problemId.':'.$part.':'.$response;
  276:                 $Str .= '<td><input type="submit" name="Analyze:::'.$value;
  277:                 $Str .= '" value="';
  278:                 $Str .= 'Part '.$part.' Response '.$response;
  279:                 $Str .= '" /></td></tr>'."\n";
  280:             }
  281:             $count++;
  282:         }
  283:         $Str .= '</table><br>'."\n";
  284:     }
  285: 
  286:     return $Str;
  287: }
  288: 
  289: #---- END Problem Analysis Web Page ------------------------------------------
  290: 
  291: #---- Analyze Web Page -------------------------------------------------------
  292: 
  293: #restore the student submissions and finding the result
  294: =pod
  295: sub OpStatus {
  296:     my ($problemID, $student, $ConceptData, $foil_to_concept,
  297:         $analyzeData, $cache)=@_;
  298: 
  299:     my $ids = $analyzeData->{'parts'};
  300: 
  301:     my @True = ();
  302:     my @False = ();
  303:     my $flag=0;
  304: 
  305:     my $tries=0;
  306: 
  307:     foreach my $id (@$ids) {
  308: 	my ($part, $response) = split(/\./, $id);
  309:         my $time=$cache->{$student.':'.$problemID.':'.$part.':timestamp'};
  310:         my @submissions = split(':::', $cache->{$student.':'.$problemID.':'.
  311:                                                 $part.':'.$response.
  312:                                                 ':submission'});
  313:         foreach my $Resp (@submissions) {
  314:             my %submission=&Apache::lonnet::str2hash($Resp);
  315:             foreach (keys(%submission)) {
  316:                 if($submission{$_}) {
  317:                     my $answer = $analyzeData->{$id.'.foil.value.'.$_};
  318:                     if($submission{$_} eq $answer) {
  319:                         &Decide("true", $foil_to_concept->{$_},
  320:                                 $time, $ConceptData);
  321:                     } else {
  322:                         &Decide("false", $foil_to_concept->{$_},
  323:                                 $time, $ConceptData);
  324:                     }
  325:                 }
  326:             }
  327:         }
  328:     }
  329: 
  330:     return;
  331: }
  332: =cut
  333: 
  334: sub OpStatus {
  335:     my ($problemID, $student, $ConceptData, $foil_to_concept,
  336:         $analyzeData, $cache, $courseID)=@_;
  337: 
  338:     my $ids = $analyzeData->{'parts'};
  339:     my ($uname,$udom)=split(/\:/,$student);
  340:     my $symb  = $cache->{$problemID.':problem'};
  341: 
  342:     my @True = ();
  343:     my @False = ();
  344:     my $flag=0;
  345:     my $tries=0;
  346: 
  347: #    $jr->print("<br> ID= $problemID <br> student= $student<br> prob= $symb<br>");
  348: 
  349:     foreach my $id (@$ids) {
  350: 	my ($part, $response) = split(/\./, $id);
  351: #=pod
  352:     my %reshash=&Apache::lonnet::restore($symb,$courseID,$udom,$uname);
  353:     if ($reshash{'version'}) {
  354:         my $tries=0;
  355: 	#&Apache::lonhomework::showhash(%$analyzeData);
  356: 	for (my $version=1;$version<=$reshash{'version'};$version++) {
  357: 	    my $time=$reshash{"$version:timestamp"};
  358: 
  359: 	    foreach my $key (sort(split(/\:/,$reshash{$version.':keys'}))) {
  360: 		if (($key=~/\.(\w+)\.(\w+)\.submission$/)) {
  361: 		    my $Id1 = $1; my $Id2 = $2;
  362: 		    #check if this is a repeat submission, if so skip it
  363:           	    if ($reshash{"$version:resource.$Id1.previous"}) { next; }
  364: 		    #if no solved this wasn't a real submission, ignore it
  365: 		    if (!defined($reshash{"$version:resource.$Id1.solved"})) {
  366: 			&Apache::lonxml::debug("skipping ");
  367: 			next;
  368: 		    }
  369: 		    my $Resp = $reshash{"$version:$key"};
  370: 		    my %submission=&Apache::lonnet::str2hash($Resp);
  371: 		    foreach (keys %submission) {
  372: 			my $Ansr = $analyzeData->{"$Id1.$Id2.foil.value.$_"};
  373:                     	if($submission{$_} eq $Ansr) {
  374:                         	&Decide("true", $foil_to_concept->{$_},
  375:                                 	$time, $ConceptData);
  376:                     	} else {
  377:                         	&Decide("false", $foil_to_concept->{$_},
  378: 					$time, $ConceptData);
  379:                     	}
  380: 		    }
  381: 	        }
  382: 	    }
  383:         }
  384:     }
  385: #=cut
  386: =pod
  387:         my $time=$cache->{$student.':'.$problemID.':'.$part.':timestamp'};
  388: 	my @submissions = split(':::', $cache->{$student.':'.$problemID.':'.
  389:                                                $part.':'.$response.
  390:                                                 ':submission'});
  391:         foreach my $Resp (@submissions) {
  392:             my %submission=&Apache::lonnet::str2hash($Resp);
  393:             foreach (keys(%submission)) {
  394:                 if($submission{$_}) {
  395:                     my $answer = $analyzeData->{$id.'.foil.value.'.$_};
  396:                     if($submission{$_} eq $answer) {
  397:                         &Decide("true", $foil_to_concept->{$_},
  398:                                 $time, $ConceptData);
  399:                     } else {
  400:                         &Decide("false", $foil_to_concept->{$_},
  401:                                 $time, $ConceptData);
  402:                     }
  403:                 }
  404:             }
  405:         }
  406: =cut
  407:     }
  408: 
  409:     return;
  410: }
  411: 
  412: =pod
  413: sub OpStatus {
  414:     my ($rid,$student,$ConceptData,$foil_to_concept,$analyzeData,$cache)=@_;
  415:     my ($uname,$udom)=split(/\:/,$student);
  416:     my $code='U';
  417:     $rid=~/(\d+)\.(\d+)/;
  418:     my $symb=&Apache::lonnet::declutter($hash{'map_id_'.$1}).'___'.$2.'___'.
  419: 	     &Apache::lonnet::declutter($hash{'src_'.$rid});
  420:     my %reshash=&Apache::lonnet::restore($symb,$cid,$udom,$uname);
  421:     my @True = ();
  422:     my @False = ();
  423:     my $flag=0;
  424:     if ($reshash{'version'}) {
  425:         my $tries=0;
  426: 	&Apache::lonhomework::showhash(%Answer);
  427: 	for (my $version=1;$version<=$reshash{'version'};$version++) {
  428: 	    my $time=$reshash{"$version:timestamp"};
  429: 
  430: 	    foreach my $key (sort(split(/\:/,$reshash{$version.':keys'}))) {
  431: 		if (($key=~/\.(\w+)\.(\w+)\.submission$/)) {
  432: 		    my $Id1 = $1; my $Id2 = $2;
  433: 		    #check if this is a repeat submission, if so skip it
  434:           	    if ($reshash{"$version:resource.$Id1.previous"}) { next; }
  435: 		    #if no solved this wasn't a real submission, ignore it
  436: 		    if (!defined($reshash{"$version:resource.$Id1.solved"})) {
  437: 			&Apache::lonxml::debug("skipping ");
  438: 			next;
  439: 		    }
  440: 		    my $Resp = $reshash{"$version:$key"};
  441: 		    my %submission=&Apache::lonnet::str2hash($Resp);
  442: 		    foreach (keys %submission) {
  443: 			my $Ansr = $Answer{"$Id1.$Id2.foil.value.$_"};
  444: 			if ($submission{$_}) {
  445: 			    if ($submission{$_} eq $Ansr) {
  446: 				&Decide("true",$_,$time );
  447: 			    }
  448: 			    else {&Decide("false",$_,$time );}
  449: 			}
  450: 		    }
  451: 	        }
  452: 	    }
  453:         }
  454:     }
  455: }
  456: =cut
  457: 
  458: sub DrawGraph {
  459:     my ($k,$Src,$Concepts,$ConceptData)=@_;
  460:     my $Max=0;
  461:     my @data1;
  462:     my @data2;
  463: 
  464:     # Adjust Data and find the Max
  465:     for (my $n=0; $n<(scalar @$Concepts); $n++ ) {
  466: 	my $tmp=$Concepts->[$n];
  467: 	$data1[$n]=$ConceptData->{$tmp.'.'.$k.'.true'};
  468: 	$data2[$n]=$ConceptData->{$tmp.'.'.$k.'.false'};
  469: 	my $Sum=$data1[$n]+$data2[$n];
  470: 	if($Max < $Sum) {
  471:             $Max=$Sum;
  472:         }
  473:     }
  474:     for (my $n=0; $n<(scalar @$Concepts); $n++ ) {
  475: 	if ($data1[$n]+$data2[$n]<$Max) {
  476: 	    $data2[$n]+=$Max-($data1[$n]+$data2[$n]);
  477: 	}
  478:     }
  479:     my $P_No = (scalar @data1);
  480: 
  481:     if($Max > 1) { 
  482: 	$Max += (10 - $Max % 10);
  483: 	$Max = int($Max);
  484:     } else {
  485:         $Max = 1;
  486:     }
  487: 
  488:     my $Titr=($ConceptData->{'Interval'}>1) ? $Src.'_interval_'.($k+1) : $Src;
  489: #    $GData=$Titr.'&Concepts'.'&'.'Answers'.'&'.$Max.'&'.$P_No.'&'.$data1.'&'.$data2;
  490:     my $GData = '';
  491:     $GData  = $Titr.'&Concepts&Answers&'.$Max.'&'.$P_No.'&';
  492:     $GData .= (join(',',@data1)).'&'.(join(',',@data2));
  493: 
  494:     return '<IMG src="/cgi-bin/graph.gif?'.$GData.'" border=1/>';
  495: }
  496: 
  497: sub DrawTable {
  498:     my ($k,$Concepts,$ConceptData)=@_;
  499:     my $Max=0;
  500:     my @data1;
  501:     my @data2;
  502:     my $Correct=0;
  503:     my $Wrong=0;
  504:     for(my $n=0; $n<(scalar @$Concepts); $n++ ) {
  505: 	my $tmp=$Concepts->[$n];
  506: 	$data1[$n]=$ConceptData->{$tmp.'.'.$k.'.true'};
  507: 	$Correct+=$data1[$n];
  508: 	$data2[$n]=$ConceptData->{$tmp.'.'.$k.'.false'};
  509: 	$Wrong+=$data2[$n];
  510: 	my $Sum=$data1[$n]+$data2[$n];
  511: 	if($Max < $Sum) {
  512:             $Max=$Sum;
  513:         }
  514:     }
  515:     for(my $n=0; $n<(scalar @$Concepts); $n++ ) {
  516: 	if ($data1[$n]+$data2[$n]<$Max) {
  517: 	    $data2[$n]+=$Max-($data1[$n]+$data2[$n]);
  518: 	}
  519:     }
  520:     my $P_No = (scalar @data1);
  521:     my $Str = '';
  522: #    $Str .= '<br><b>From: ['.localtime($ConceptData->{'Int.'.($k-1)});
  523: #    $Str .= '] To: ['.localtime($ConceptData->{"Int.$k"}).']</b>';
  524:     $Str .= "\n".'<table border=2>'.
  525:             "\n".'<tr>'.
  526:             "\n".'<th> # </th>'.
  527:             "\n".'<th> Concept </th>'.
  528:             "\n".'<th> Correct </th>'.
  529:             "\n".'<th> Wrong </th>'.
  530:             "\n".'</tr>';
  531: 
  532:     for(my $n=0; $n<(scalar @$Concepts); $n++ ) {
  533: 	$Str .= '<tr>'."\n";
  534:         $Str .= '<td>'.($n+1).'</td>'."\n";
  535:         my ($currentConcept) = split('::',$Concepts->[$n]);
  536:         $Str .= '<td bgcolor="EEFFCC">'.$currentConcept;
  537:         $Str .= '</td>'."\n";
  538:         $Str .= '<td bgcolor="DDFFDD">'.$data1[$n].'</td>'."\n";
  539:         $Str .= '<td bgcolor="FFDDDD">'.$data2[$n].'</td>'."\n";
  540:         $Str .= '</tr>'."\n";
  541:     }
  542:     $Str .= '<td></td><td><b>From:['.localtime($ConceptData->{'Int.'.$k});
  543:     $Str .= '] To: ['.localtime($ConceptData->{'Int.'.($k+1)}-1);
  544:     $Str .= ']</b></td><td>'.$Correct.'</td><td>'.$Wrong.'</td>';
  545:     $Str .= '</table>'."\n";
  546: 
  547:     return $Str;
  548: #$Apache::lonxml::debug=1;
  549: #&Apache::lonhomework::showhash(%ConceptData);
  550: #$Apache::lonxml::debug=0;
  551: }
  552: 
  553: #---- END Analyze Web Page ----------------------------------------------
  554: 
  555: sub Decide {
  556:     #deciding the true or false answer belongs to each interval
  557:     my ($type,$concept,$time,$ConceptData)=@_; 
  558:     my $k=0;
  559:     while($time > $ConceptData->{'Int.'.($k+1)} && 
  560:            $k < $ConceptData->{'Interval'}) {
  561:         $k++;
  562:     }
  563:     $ConceptData->{$concept.'.'.$k.'.'.$type}++;
  564: 
  565:     return;
  566: }
  567: 
  568: sub InitAnalysis {
  569:     my ($uri,$part,$responseId,$problem,$student,$courseID)=@_;
  570:     my ($name,$domain)=split(/\:/,$student);
  571: 
  572:     my %analyzeData;
  573:     # Render the student's view of the problem.  $Answ is the problem 
  574:     # Stringafied
  575:     my $Answ=&Apache::lonnet::ssi($uri,('grade_target'   => 'analyze',
  576:                                         'grade_username' => $name,
  577:                                         'grade_domain'   => $domain,
  578:                                         'grade_courseid' => $courseID,
  579:                                         'grade_symb'     => $problem));
  580:     my ($Answer)=&Apache::lonnet::str2hashref($Answ);
  581: 
  582:     my $found = 0;
  583:     my @parts=();
  584:     if(defined($responseId)) {
  585:         foreach (@{$Answer->{'parts'}}) {
  586:             if($_ eq $part.'.'.$responseId) {
  587:                 push(@parts, $_);
  588:                 $found = 1;
  589:                 last;
  590:             }
  591:         }
  592:     } else {
  593:         foreach (@{$Answer->{'parts'}}) {
  594:             if($_ =~ /$part/) {
  595:                 push(@parts, $_);
  596:                 $found = 1;
  597:                 last;
  598:             }
  599:         }
  600:     }
  601: 
  602:     if($found == 0) {
  603:         $analyzeData{'error'} = 'No parts matching selected values';
  604:         return \%analyzeData;
  605:     }
  606: 
  607:     my @Concepts=();
  608:     my %foil_to_concept;
  609:     foreach my $currentPart (@parts) {
  610:         if(defined($Answer->{$currentPart.'.concepts'})) {
  611:             foreach my $concept (@{$Answer->{$currentPart.'.concepts'}}) {
  612:                 push(@Concepts, $concept);
  613:                 foreach my $foil (@{$Answer->{$currentPart.'.concept.'.
  614:                                             $concept}}) {
  615:                     $analyzeData{$currentPart.'.foil.value.'.$foil} =
  616:                         $Answer->{$currentPart.'.foil.value.'.$foil};
  617:                     $foil_to_concept{$foil} = $concept;
  618:                 }
  619:             }
  620:         } else {
  621:             foreach (keys(%$Answer)) {
  622:                 if(/$currentPart.foil\.value\.(.*)$/) {
  623:                     push(@Concepts, $1);
  624:                     $foil_to_concept{$1} = $1;
  625:                     $analyzeData{$currentPart.'.foil.value.'.$1} =
  626:                         $Answer->{$currentPart.'.foil.value.'.$1};
  627:                 }
  628:             }
  629:         }
  630:     }
  631: 
  632:     $analyzeData{'parts'} = \@parts;
  633:     $analyzeData{'concepts'} = \@Concepts;
  634:     $analyzeData{'foil_to_concept'} = \%foil_to_concept;
  635: 
  636:     return \%analyzeData;
  637: }
  638: 
  639: sub Interval {
  640:     my ($part,$symb,$interval,$Concepts,$ConceptData)=@_;
  641:     my $Int=$interval;
  642:     my $due = &Apache::lonnet::EXT('resource.'.$part.'.duedate',$symb);
  643:     my $opn = &Apache::lonnet::EXT('resource.'.$part.'.opendate',$symb);
  644:     my $add=int(($due-$opn)/$Int);
  645:     $ConceptData->{'Int.0'}=$opn;
  646:     for(my $i=1; $i<$Int; $i++) {
  647: 	$ConceptData->{'Int.'.$i}=$opn+$i*$add;
  648:     }
  649:     $ConceptData->{'Int.'.$Int}=$due;
  650:     for(my $i=0; $i<$Int; $i++) {
  651: 	for(my $n=0; $n<(scalar @$Concepts); $n++ ) {
  652: 	    my $tmp=$Concepts->[$n];
  653: 	    $ConceptData->{$tmp.'.'.$i.'.true'}=0;
  654: 	    $ConceptData->{$tmp.'.'.$i.'.false'}=0;
  655: 	}
  656:     }
  657: }
  658: 1;
  659: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>