--- loncom/interface/loncoursedata.pm 2004/02/06 19:35:00 1.116 +++ loncom/interface/loncoursedata.pm 2004/03/22 17:25:26 1.126 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: loncoursedata.pm,v 1.116 2004/02/06 19:35:00 matthew Exp $ +# $Id: loncoursedata.pm,v 1.126 2004/03/22 17:25:26 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -182,7 +182,7 @@ sub get_sequence_assessment_data { next; } next if (! ref($curRes)); - next if (! $curRes->is_problem());# && !$curRes->randomout); + next if (! $curRes->is_problem() && $curRes->src() !~ /\.survey$/); # Okay, from here on out we only deal with assessments $title = $curRes->title(); $title =~ s/\:/\&\#058;/g; @@ -1867,12 +1867,14 @@ populated and all local caching variable properly. This means you need to call &ensure_current_data for the students you are concerned with prior to calling this routine. -Inputs: $students, $symb, $part, $courseid +Inputs: $Sections, $status, $symb, $part, $courseid, $starttime, $endtime =over 4 -=item $students is an array of hash references. -Each hash must contain at least the 'username' and 'domain' of a student. +=item $Sections Array ref containing section names for students. +'all' is allowed to be the first (and only) item in the array. + +=item $status String describing the status of students =item $symb is the symb for the problem. @@ -1880,6 +1882,9 @@ Each hash must contain at least the 'use =item $courseid is the course id, of course! +=item $starttime and $endtime are unix times which to use to limit +the statistical data. + =back Outputs: See the code for up to date information. A hash reference is @@ -1915,7 +1920,7 @@ able to answer it correctly. ################################################ ################################################ sub get_problem_statistics { - my ($Sections,$status,$symb,$part,$courseid) = @_; + my ($Sections,$status,$symb,$part,$courseid,$starttime,$endtime) = @_; return if (! defined($symb) || ! defined($part)); $courseid = $ENV{'request.course.id'} if (! defined($courseid)); # @@ -1927,16 +1932,21 @@ sub get_problem_statistics { my $dbh = &Apache::lonmysql::get_dbh(); return undef if (! defined($dbh)); # + # Clean out the table $dbh->do('DROP TABLE '.$stats_table); # May return an error my $request = 'CREATE TEMPORARY TABLE '.$stats_table.' '. 'SELECT a.student_id,a.solved,a.award,a.awarded,a.tries '. 'FROM '.$performance_table.' AS a '; + # + # See if we need to include some requirements on the students if ((defined($Sections) && lc($Sections->[0]) ne 'all') || (defined($status) && lc($status) ne 'any')) { $request .= 'NATURAL LEFT JOIN '.$student_table.' AS b '; } $request .= ' WHERE a.symb_id='.$symb_id.' AND a.part_id='.$part_id; + # + # Limit the students included to those specified if (defined($Sections) && lc($Sections->[0]) ne 'all') { $request .= ' AND ('. join(' OR ', map { "b.section='".$_."'" } @$Sections @@ -1945,22 +1955,34 @@ sub get_problem_statistics { if (defined($status) && lc($status) ne 'any') { $request .= " AND b.status='".$status."'"; } + # + # Limit by starttime and endtime + my $time_requirements = undef; + if (defined($starttime)) { + $time_requirements .= 'a.timestamp>='.$starttime; + if (defined($endtime)) { + $time_requirements .= ' AND a.timestamp<='.$endtime; + } + } elsif (defined($endtime)) { + $time_requirements .= 'a.timestamp<='.$endtime; + } + if (defined($time_requirements)) { + $request .= ' AND '.$time_requirements; + } + # + # Finally, execute the request to create the temporary table $dbh->do($request); -# &Apache::lonnet::logthis('request = '.$/.$request); + # + # Collect the first suite of statistics $request = 'SELECT COUNT(*),SUM(tries),MAX(tries),AVG(tries),STD(tries) '. 'FROM '.$stats_table; my ($num,$tries,$mod,$mean,$STD) = &execute_SQL_request ($dbh,$request); -# &Apache::lonnet::logthis('request = '.$/.$request); $request = 'SELECT SUM(awarded) FROM '.$stats_table; my ($Solved) = &execute_SQL_request($dbh,$request); -# &Apache::lonnet::logthis('request = '.$/.$request); $request = 'SELECT SUM(awarded) FROM '.$stats_table. " WHERE solved='correct_by_override'"; -# &Apache::lonnet::logthis('request = '.$/.$request); my ($solved) = &execute_SQL_request($dbh,$request); -# $Solved = int($Solved); -# $solved = int($solved); # $num = 0 if (! defined($num)); $tries = 0 if (! defined($tries)); @@ -1969,9 +1991,10 @@ sub get_problem_statistics { $Solved = 0 if (! defined($Solved)); $solved = 0 if (! defined($solved)); # + # Compute the more complicated statistics my $DegOfDiff = 'nan'; $DegOfDiff = 1-($Solved)/$tries if ($tries>0); - + # my $SKEW = 'nan'; my $wrongpercent = 0; if ($num > 0) { @@ -1981,26 +2004,25 @@ sub get_problem_statistics { $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; } # -# $dbh->do('DROP TABLE '.$stats_table); # May return an error + # Drop the temporary table + $dbh->do('DROP TABLE '.$stats_table); # May return an error # # Store in metadata - # if ($num) { my %storestats=(); - + # my $urlres=(&Apache::lonnet::decode_symb($symb))[2]; - + # $storestats{$courseid.'___'.$urlres.'___timestamp'}=time; $storestats{$courseid.'___'.$urlres.'___stdno'}=$num; $storestats{$courseid.'___'.$urlres.'___avetries'}=$mean; $storestats{$courseid.'___'.$urlres.'___difficulty'}=$DegOfDiff; - + # $urlres=~/^(\w+)\/(\w+)/; &Apache::lonnet::put('nohist_resevaldata',\%storestats,$1,$2); } # # Return result - # return { num_students => $num, tries => $tries, max_tries => $mod, @@ -2025,6 +2047,7 @@ sub execute_SQL_request { return (); } + sub get_student_data { my ($students,$courseid) = @_; $courseid = $ENV{'request.course.id'} if (! defined($courseid)); @@ -2064,7 +2087,7 @@ sub RD_tries { return 5; } sub RD_sname { return 6; } sub get_response_data { - my ($students,$symb,$response,$courseid) = @_; + my ($Sections,$enrollment,$symb,$response,$courseid) = @_; return undef if (! defined($symb) || ! defined($response)); $courseid = $ENV{'request.course.id'} if (! defined($courseid)); @@ -2075,6 +2098,18 @@ sub get_response_data { # my $dbh = &Apache::lonmysql::get_dbh(); return undef if (! defined($dbh)); + # + my $student_requirements; + if ( (defined($Sections) && $Sections->[0] ne 'all')) { + $student_requirements = '('. + join(' OR ', map { "d.section='".$_."'" } @$Sections + ).')'; + } + # + my $enrollment_requirements=undef; + if (defined($enrollment) && $enrollment ne 'Any') { + $enrollment_requirements = "d.status='".$enrollment."'"; + } my $request = 'SELECT '. 'a.student_id, a.awarddetail, a.response_specific_value, '. 'a.submission, b.timestamp, c.tries, d.student '. @@ -2089,13 +2124,15 @@ sub get_response_data { 'ON a.student_id=d.student_id '. 'WHERE '. 'a.symb_id='.$symb_id.' AND a.response_id='.$response_id; - if (defined($students)) { - $request .= ' AND ('. - join(' OR ', map {'a.student_id='. - &get_student_id($_->{'username'}, - $_->{'domain'}) - } @$students - ).')'; + if (defined($student_requirements) || defined($enrollment_requirements)) { + $request .= ' AND '; + if (defined($student_requirements)) { + $request .= $student_requirements.' AND '; + } + if (defined($enrollment_requirements)) { + $request .= $enrollment_requirements.' AND '; + } + $request =~ s/( AND )$//; } $request .= ' ORDER BY b.timestamp'; # &Apache::lonnet::logthis("request =\n".$request); @@ -2107,8 +2144,69 @@ sub get_response_data { } my $dataset = $sth->fetchall_arrayref(); if (ref($dataset) eq 'ARRAY' && scalar(@$dataset)>0) { + # Clear the \'s from around the submission + for (my $i =0;$i[$i]->[3] =~ s/(\'$|^\')//g; + } + return $dataset; + } +} + + +sub RDs_awarddetail { return 3; } +sub RDs_submission { return 2; } +sub RDs_timestamp { return 1; } +sub RDs_tries { return 0; } +sub RDs_awarded { return 4; } + +sub get_response_data_by_student { + my ($student,$symb,$response,$courseid) = @_; + return undef if (! defined($symb) || + ! defined($response)); + $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + # + &setup_table_names($courseid); + my $symb_id = &get_symb_id($symb); + my $response_id = &get_part_id($response); + # + my $student_id = &get_student_id($student->{'username'}, + $student->{'domain'}); + # + my $dbh = &Apache::lonmysql::get_dbh(); + return undef if (! defined($dbh)); + my $request = 'SELECT '. + 'c.tries, b.timestamp, a.submission, a.awarddetail, e.awarded '. + 'FROM '.$fulldump_response_table.' AS a '. + 'LEFT JOIN '.$fulldump_timestamp_table.' AS b '. + 'ON a.symb_id=b.symb_id AND a.student_id=b.student_id AND '. + 'a.transaction = b.transaction '. + 'LEFT JOIN '.$fulldump_part_table.' AS c '. + 'ON a.symb_id=c.symb_id AND a.student_id=c.student_id AND '. + 'a.part_id=c.part_id AND a.transaction = c.transaction '. + 'LEFT JOIN '.$student_table.' AS d '. + 'ON a.student_id=d.student_id '. + 'LEFT JOIN '.$performance_table.' AS e '. + 'ON a.symb_id=e.symb_id AND a.part_id=e.part_id AND '. + 'a.student_id=e.student_id AND c.tries=e.tries '. + 'WHERE '. + 'a.symb_id='.$symb_id.' AND a.response_id='.$response_id. + ' AND a.student_id='.$student_id.' ORDER BY b.timestamp'; +# &Apache::lonnet::logthis("request =\n".$request); + my $sth = $dbh->prepare($request); + $sth->execute(); + if ($dbh->err) { + &Apache::lonnet::logthis('error = '.$dbh->errstr()); + return undef; + } + my $dataset = $sth->fetchall_arrayref(); + if (ref($dataset) eq 'ARRAY' && scalar(@$dataset)>0) { + # Clear the \'s from around the submission + for (my $i =0;$i[$i]->[2] =~ s/(\'$|^\')//g; + } return $dataset; } + return undef; # error occurred } sub RT_student_id { return 0; } @@ -2171,7 +2269,7 @@ sub get_response_time_data { ################################################ ################################################ sub get_student_scores { - my ($Sections,$Symbs,$enrollment,$courseid) = @_; + my ($Sections,$Symbs,$enrollment,$courseid,$starttime,$endtime) = @_; $courseid = $ENV{'request.course.id'} if (! defined($courseid)); &setup_table_names($courseid); my $dbh = &Apache::lonmysql::get_dbh(); @@ -2182,8 +2280,8 @@ sub get_student_scores { if (defined($Symbs) && @$Symbs) { $symb_requirements = '('. join(' OR ', map{ "(a.symb_id='".&get_symb_id($_->{'symb'}). - "' AND a.part_id='".&get_part_id($_->{'part'}). - "')" + "' AND a.part_id='".&get_part_id($_->{'part'}). + "')" } @$Symbs).')'; } # @@ -2198,6 +2296,16 @@ sub get_student_scores { if (defined($enrollment) && $enrollment ne 'Any') { $enrollment_requirements = "b.status='".$enrollment."'"; } + # + my $time_requirements = undef; + if (defined($starttime)) { + $time_requirements .= "a.timestamp>='".$starttime."'"; + if (defined($endtime)) { + $time_requirements .= " AND a.timestamp<='".$endtime."'"; + } + } elsif (defined($endtime)) { + $time_requirements .= "a.timestamp<='".$endtime."'"; + } ## ## my $request = 'CREATE TEMPORARY TABLE IF NOT EXISTS '.$tmptable. @@ -2220,7 +2328,10 @@ sub get_student_scores { if (defined($enrollment_requirements)) { $request .= $enrollment_requirements.' AND '; } - $request =~ s/ AND $//; + if (defined($time_requirements)) { + $request .= $time_requirements.' AND '; + } + $request =~ s/ AND $//; # Strip of the trailing ' AND '. $request .= ' GROUP BY a.student_id'; # &Apache::lonnet::logthis("request = \n".$request); my $sth = $dbh->prepare($request);