Correct Answers | '. - "\n".'Wrong Answers | '. - "\n".'From | '. - "\n".'To | '. - "\n".'
---|---|---|---|
$data1 | ". - "\n"."$data2 | ". - "\n"."".localtime($ConceptData{'Int.'.($k-1)})." | ". - "\n"."".localtime($ConceptData{'Int.'.$k}-1)." | ". - "\n"."
'.
- "\n".'
# | '. - "\n".'Problem Title | '. - "\n".'Resouse | '. - "\n".'Address | '. - "\n".'
---|---|---|---|
$P_No | ". - "\n"."".$Temp." | ". - "\n"."".$hash{'src_'.$OpResp{$_}}." | ". - "\n"."".''.' | '. - "\n"."
# | '. - "\n".'Set Title | '. - "\n".'Results | '. - "\n".'Tries | '. - "\n".'
---|---|---|---|
$SetNo | ". - "\n"."$Set | ". - "\n"."$PtrCod | ". - "\n"."$PtrTry | ". - "\n"."
P# | '."\n"; - for ( my $nIdx=0; $nIdx < $ColNo; $nIdx++ ) { - $Result .= ''.''.' | '."\n"; - } - $Result .= "\n".'
---|
'. - ' #Stdnts: Total Number of Students opened the problem.'; - - $r->print($Ptr); - $r->rflush(); - - if ((-e "$CacheDB")&&($ENV{'form.sort'} ne 'Recalculate Statistics')) { - if (tie(%CachData,'GDBM_File',"$CacheDB",&GDBM_READER,0640)) { - tie(%GraphDat,'GDBM_File',$GraphDB,&GDBM_WRCREAT,0640); - &Cache_Statistics(); - } - else { - $r->print("Unable to tie hash to db file"); - } - } - else { - if (tie(%CachData,'GDBM_File',$CacheDB,&GDBM_WRCREAT,0640)) { - tie(%GraphDat,'GDBM_File',$GraphDB,&GDBM_WRCREAT,0640); - foreach (keys %DiscFac) {delete $CachData{$_};} - foreach (keys %CachData) {delete $CachData{$_};} - $DiscFlag=0; - &Build_Statistics(); - } - else { - $r->print("Unable to tie hash to db file"); - } - } - -# $r->print('Total instances of the problems : '.($p_count*($#students+1))); - untie(%CachData); - untie(%GraphDat); -} +=item $curr_student The student currently being examined + +=item $prev_student The student previous in the classlist + +=item $next_student The student next in the classlist + +=back +$curr_student, $prev_student, and $next_student may not be defined, depending +upon the calling context. -# ------------------------------------- Find the section of student in a course +=cut -sub usection { - my ($udom,$unam,$courseid,$ActiveFlag)=@_; - $courseid=~s/\_/\//g; - $courseid=~s/^(\w)/\/$1/; - foreach (split(/\&/,&Apache::lonnet::reply('dump:'. - $udom.':'.$unam.':roles', - &Apache::lonnet::homeserver($unam,$udom)))){ - my ($key,$value)=split(/\=/,$_); - $key=&Apache::lonnet::unescape($key); - if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) { - my $section=$1; - if ($key eq $courseid.'_st') { $section=''; } - my ($dummy,$end,$start)=split(/\_/,&Apache::lonnet::unescape($value)); - if ( $ActiveFlag ne 'Any' ) { - my $now=time; - my $notactive=0; - if ($start) { - if ($now<$start) { $notactive=1; } - } - if ($end) { - if ($now>$end) { $notactive=1; } - } - if ((($ActiveFlag eq 'Expired') && $notactive == 1) || - (($ActiveFlag eq 'Active') && $notactive == 0 ) ) { - return $section; - } - else { return '-1'; } - } - return $section; +####################################################### +####################################################### +sub PrepareClasslist { + my $r = shift; + my %Sections; + &clear_classlist_variables(); + # + # Retrieve the classlist + my $cid = $ENV{'request.course.id'}; + my $cdom = $ENV{'course.'.$cid.'.domain'}; + my $cnum = $ENV{'course.'.$cid.'.num'}; + my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid, + $cdom,$cnum); + my %valid_section; + if (exists($ENV{'form.Section'}) && $ENV{'form.Section'} !~ /(all|any)/) { + if (ref($ENV{'form.Section'})) { + foreach (@$ENV{'form.section'}) { + $valid_section{$_}++; + } + } else { + $valid_section{$_}++; + } + } + # + # Process the classlist + while (my ($student,$student_data) = each (%$classlist)) { + my $studenthash = (); + for (my $i=0; $i< scalar(@$field_names);$i++) { + $studenthash->{$field_names->[$i]}=$student_data->[$i]; + } + push (@FullClasslist,$studenthash); + # + # Build up a list of sections + my $section = $studenthash->{'section'}; + $section = 'no section' if (! defined($section) || $section =~/^\s*/ ); + $Sections{$section}++; + # + # Only put in the list those students we are interested in + if (defined($ENV{'form.Section'}) && + $ENV{'form.Section'} !~ /(all|any)/ && + ! exists($valid_section{$section})) { + next; + } + push (@Students,$studenthash); + } + # + # Put the consolidated section data in the right place + @Sections = sort {$a<=>$b} keys(%Sections); + # + # Sort the Students + my $sortby = 'fullname'; + @Students = sort {$a->{$sortby} <=> $b->{$sortby}} @Students; + # + # Now deal with that current student thing.... + if (exists($ENV{'form.StudentAssessmentStudent'})) { + my ($current_uname,$current_dom) = + split(':',$ENV{'form.StudentAssessmentStudent'}); + my $i; + for ($i = 0; $i<=$#Students; $i++) { + next if (($Students[$i]->{'username'} ne $current_uname) || + ($Students[$i]->{'domain'} ne $current_dom)); + last; # If we get here, we have our student. + } + if ($i == 0) { + $prev_student = 'none'; + } else { + $prev_student = $Students[$i-1]; + } + if ($i == $#Students) { + $next_student = 'none'; + } else { + $next_student = $Students[$i+1]; } } - return '-1'; } +####################################################### +####################################################### -# ------ Dump the Student's DB file and handling the data for statistics table -sub ExtractStudentData { - my $student=shift; - my ($sname,$sdom) = split( /\:/, $student ); - my %result = &Apache::lonnet::dump($cid,$sdom,$sname); - my $ResId; - my $PrOrd; - my $Dis = ''; - my $Code; - my $Tries; - my $ParCr; - my $TotalTries = 0; - my $TotalOpend = 0; - my $ProbSolved = 0; - my $ProbTot = 0; - my $TimeTot = 0; - my $TotParCr = 0; - my $Wrongs; - my %TempHash; - my $Version; - my $LatestVersion; - my $SecLimit; - my $MapLimit; - my ($temp)=keys(%result); - unless ($temp=~/^error\:/) { - foreach my $CurCol(@cols) { - ($PrOrd,$ResId)=split(/\:/,$CurCol); - if ( !$CurCol ) { next; } - $ResId=~/(\d+)\.(\d+)/; - my $MapId=$1; - my $PrbId=$2; - my $MapOrg = $hash{'map_id_'.$MapId}; - my $Map = &Apache::lonnet::declutter($MapOrg); - if ( $CurMap ne 'All Maps' ) { - my ( $ResMap, $NameMap ) = split(/\=/,$CurMap); - if ( $Map ne $ResMap ) { next; } - } - my $meta=$hash{'src_'.$ResId}; - my $PartNo = 0; - $Dis .= ':'; - undef %TempHash; - - foreach (split(/\,/,&Apache::lonnet::metadata($meta,'keys'))) { - if ($_=~/^stores\_(\w+)\_tries$/) { - my $Part=&Apache::lonnet::metadata($meta,$_.'.part'); - if ( $TempHash{"$Part"} eq '' ) { - $TempHash{"$Part"} = $Part; - $TempHash{$PartNo}=$Part; - $TempHash{"$Part.Code"} = 'U'; - $TempHash{"$Part.PrOrd"} = $PrOrd+$PartNo; - $PartNo++; - } - #my $Part=&Apache::lonnet::metadata($meta,$_.'.part'); - } - } - &Apache::lonnet::declutter( $hash{'src_'.$ResId} ); - my $URI = $hash{'src_'.$ResId}; - my $Prob = $Map.'___'.$PrbId.'___'. - &Apache::lonnet::declutter($URI); - $Code='U'; - $Tries = 0; - $ParCr = 0; - $Wrongs = 0; - $LatestVersion = $result{"version:$Prob"}; - if ( $LatestVersion ) { - for ( my $Version=1; $Version<=$LatestVersion; $Version++ ) { - my $vkeys = $result{"$Version:keys:$Prob"}; - my @keys = split(/\:/,$vkeys); - foreach my $Key (@keys) { - if (($Key=~/\.(\w+)\.solved$/) && ($Key!~/^\d+\:/)) { - my $Part = $1; - $Tries = $result{"$Version:$Prob:resource.$Part.tries"}; - $ParCr = $result{"$Version:$Prob:resource.$Part.awarded"}; - my $Time = $result{"$Version:$Prob:timestamp"}; - $TempHash{"$Part.Time"} = ($Time) ? $Time : 0; - $TempHash{"$Part.Tries"} = ($Tries) ? $Tries : 0; - $TempHash{"$Part.ParCr"} = ($ParCr) ? $ParCr : 0; - $TotalTries += $TempHash{"$Part.Tries"}; - $TotParCr += $TempHash{"$Part.ParCr"}; - my $Val = $result{"$Version:$Prob:resource.$Part.solved"}; - if ( $Val eq 'correct_by_student' ) - { $Wrongs = $Tries - 1; $Code = 'C'; } - elsif ( $Val eq 'correct_by_override' ) - { $Wrongs = $Tries - 1; $Code = 'O'; } - elsif ( $Val eq 'incorrect_attempted' || - $Val eq 'incorrect_by_override' ) - { $Wrongs = $Tries; $Code = 'I'; } - $TempHash{"$Part.Code"} = $Code; - $TempHash{"$Part.Wrongs"} = $Wrongs; - } - } - } - for ( my $n = 0; $n < $PartNo; $n++ ) { - my $part = $TempHash{$n}; - my $Yes = 0; - if ( $TempHash{$part.'.Code'} eq 'C' || - $TempHash{$part.'.Code'} eq 'O' ) - {$ProbSolved++;$Yes=1;} - - # my $ptr = "$hash{'title_'.$ResId}"; - my $ptr = $TempHash{$part.'.PrOrd'}.'&'.$ResId; - - if ( $PartNo > 1 ) { - $ptr .= "*(part $part)"; - $Dis .= '&'; - } - my $Fac = ($TempHash{"$part.Tries"}) ? - ($TempHash{"$part.ParCr"}/$TempHash{"$part.Tries"}) : 0; - my $DisF; - if ( $Fac > 0 && $Fac < 1 ) { - $DisF = sprintf( "%.4f", $Fac ); - } - else {$DisF = $Fac;} -# $DisF .= '+'.$TempHash{"$part.Time"};33333333 - $TimeTot += $TempHash{"$part.Time"}; - $Dis .= $TempHash{$part.'.PrOrd'}.'='.$DisF.'+'.$Yes; - $ptr .= "&$TempHash{$part.'.Tries'}". - "&$TempHash{$part.'.Wrongs'}". - "&$TempHash{$part.'.Code'}"; - push (@list, $ptr); - $TotalOpend++; - $ProbTot++; - } +sub CheckFormElement { + my ($cache, $ENVName, $cacheName, $default)=@_; + + if(defined($ENV{'form.'.$ENVName})) { + $cache->{$cacheName} = $ENV{'form.'.$ENVName}; + } elsif(!defined($cache->{$cacheName})) { + $cache->{$cacheName} = $default; + } + + return; +} + +sub ProcessFormData{ + my ($cache)=@_; + + $cache->{'reportKey'} = 'false'; + + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['sort','download', + 'reportSelected', + 'StudentAssessmentStudent', + 'ProblemStatisticsSort']); + &CheckFormElement($cache, 'DownloadAll', 'DownloadAll', 'false'); + if ($cache->{'DownloadAll'} ne 'false') { + # Clean the hell out of that cache! + # We cannot untie the hash at this scope (stupid libgd :( ) + # So, remove every single key. What a waste of time.... + # Of course, if you are doing this you are probably resigned + # to waiting a while. + &Apache::lonnet::logthis("Cleaning out the cache file"); + while (my ($key,undef)=each(%$cache)) { + next if ($key eq 'DownloadAll'); + delete($cache->{$key}); + } + } + &CheckFormElement($cache, 'Status', 'Status', 'Active'); + &CheckFormElement($cache, 'postdata', 'reportSelected', 'Class list'); + &CheckFormElement($cache, 'reportSelected', 'reportSelected', + 'Class list'); + $cache->{'reportSelected'} = + &Apache::lonnet::unescape($cache->{'reportSelected'}); + &CheckFormElement($cache, 'sort', 'sort', 'fullname'); + &CheckFormElement($cache, 'download', 'download', 'false'); + &CheckFormElement($cache, 'StatisticsMaps', + 'StatisticsMaps', 'All Maps'); + &CheckFormElement($cache, 'StatisticsProblemSelect', + 'StatisticsProblemSelect', 'All Problems'); + &CheckFormElement($cache, 'StatisticsPartSelect', + 'StatisticsPartSelect', 'All Parts'); + if(defined($ENV{'form.Section'})) { + my @sectionsSelected = (ref($ENV{'form.Section'}) ? + @{$ENV{'form.Section'}} : + ($ENV{'form.Section'})); + $cache->{'sectionsSelected'} = join(':', @sectionsSelected); + } elsif(!defined($cache->{'sectionsSelected'})) { + $cache->{'sectionsSelected'} = $cache->{'sectionList'}; + } + + # student assessment + if(defined($ENV{'form.CreateStudentAssessment'}) || + defined($ENV{'form.NextStudent'}) || + defined($ENV{'form.PreviousStudent'})) { + $cache->{'reportSelected'} = 'Student Assessment'; + } + if(defined($ENV{'form.NextStudent'})) { + $cache->{'StudentAssessmentMove'} = 'next'; + } elsif(defined($ENV{'form.PreviousStudent'})) { + $cache->{'StudentAssessmentMove'} = 'previous'; + } else { + $cache->{'StudentAssessmentMove'} = 'selected'; + } + &CheckFormElement($cache, 'StudentAssessmentStudent', + 'StudentAssessmentStudent', 'All Students'); + $cache->{'StudentAssessmentStudent'} = + &Apache::lonnet::unescape($cache->{'StudentAssessmentStudent'}); + &CheckFormElement($cache, 'DefaultColumns', 'DefaultColumns', 'false'); + + # Problem analysis + &CheckFormElement($cache, 'Interval', 'Interval', '1'); + + # ProblemStatistcs + &CheckFormElement($cache, 'DisplayCSVFormat', + 'DisplayFormat', 'Display Table Format'); + &CheckFormElement($cache, 'ProblemStatisticsAscend', + 'ProblemStatisticsAscend', 'Ascending'); + &CheckFormElement($cache, 'ProblemStatisticsSort', + 'ProblemStatisticsSort', 'Homework Sets Order'); + &CheckFormElement($cache, 'DisplayLegend', 'DisplayLegend', + 'Hide Legend'); + &CheckFormElement($cache, 'SortProblems', 'SortProblems', + 'Sort Within Sequence'); + + # Search only form elements + my @headingColumns=(); + my @sequenceColumns=(); + my $foundColumn = 0; + if(defined($ENV{'form.ReselectColumns'})) { + my @reselected = (ref($ENV{'form.ReselectColumns'}) ? + @{$ENV{'form.ReselectColumns'}} + : ($ENV{'form.ReselectColumns'})); + foreach (@reselected) { + if(/HeadingColumn/) { + push(@headingColumns, $_); + $foundColumn = 1; + } elsif(/SequenceColumn/) { + push(@sequenceColumns, $_); + $foundColumn = 1; } - #else { - #for(my $n=0; $n<$PartNo; $n++) { - # push (@list, "$TempHash{'0'.'.PrOrd'}.':'.$ResId:0:0:U"); - # $ProbTot++; - #} - #} - } - if ( $TotalTries ) { - my $DisFac = ( $TotalTries ) ? ($TotParCr/$TotalTries) : 0; - my $DisFactor = sprintf( "%.4f", $DisFac ); - $DiscFac{$DisFactor}=$Dis; - #my $time; - #if ($ProbSolved){ - #$time = int(($TimeTot/$ProbSolved)-10000000); - #} - #$DiscFac{($DisFactor.':'.$sname.':'.$ProbTot.':'.$TotalOpend.':'. - # $TotalTries.':'.$ProbSolved.':'.$time)}=$Dis; - } + } } - #$r->print($sname.' PrCr= '.$TotParCr.' Slvd= '.$ProbSolved.' Tries='.$TotalTries.'
'. - ' Tries : Total Number of Tries for solving the problem.
'. - ' Mod : Maximunm Number of Tries for solving the problem.
'. - ' Mean : Average Number of the tries. [ Tries / #Stdnts ]
'. - ' #YES : Number of students solved the problem correctly.
'. - ' #yes : Number of students solved the problem by override.
'. - ' %Wrng : Percentage of students tried to solve the problem but'. - ' still incorrect. [ 100*((#Stdnts-(#YES+#yes))/#Stdnts) ]
'. -# ' DoDiff : Degree of Difficulty of the problem. [ Tries/(#YES+#yes+0.1) ]
'. Kashy formula - ' DoDiff : Degree of Difficulty of the problem. [ 1 - ((#YES+#yes) / Tries) ]
'. #Gerd formula - ' S.D. : Standard Deviation of the tries.'. - '[ sqrt(sum((Xi - Mean)^2)) / (#Stdnts-1)'. - ' where Xi denotes every student\'s tries ]
'. - ' Skew. : Skewness of the students tries.'. - ' [ (sqrt( sum((Xi - Mean)^3) / #Stdnts)) / (S.D.^3) ]
'. - ' Dis.F. : Discrimination Factor: A Standard for '. - 'evaluating the problem according to a Criterion
'. - ' [Applied Criterion in %27 Upper Students - '. - 'Applied the same Criterion in %27 Lower Students]
'. - ' 1st Criterion for Sorting the Students: '. - 'Sum of Partial Credit Awarded / Total Number of Tries
'. - ' 2nd Criterion for Sorting the Students: '. - 'Total number of Correct Answers / Total Number of Tries'. - '
Select Sections'; +# $Ptr .= ' | '."\n"; +# $Ptr .= ''."\n"; +# my @sectionsSelected = split(':',$cache{'sectionsSelected'}); +# my @sections = split(':',$cache{'sectionList'}); +# $Ptr .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections, +# \@sectionsSelected, +# 'Statistics'); +# $Ptr .= ' |
'."\n";
+ $Str .= '
|
'."\n"; + $Str .= ' | Select a Report | '."\n"; + $Str .= 'Student Status | |
{'reportSelected'} eq $reports->{$_}) { + $Str .= ' selected=""'; + } + $Str .= '>'.$reports->{$_}.''."\n"; } -} + $Str .= ' | '."\n"; + $Str .= ''; + $Str .= &Apache::lonhtmlcommon::StatusOptions($status, 'Statistics'); + $Str .= ' | '."\n"; + + $Str .= '