--- loncom/interface/loncoursedata.pm 2005/04/07 06:56:23 1.146 +++ loncom/interface/loncoursedata.pm 2006/04/08 06:51:47 1.158 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: loncoursedata.pm,v 1.146 2005/04/07 06:56:23 albertel Exp $ +# $Id: loncoursedata.pm,v 1.158 2006/04/08 06:51:47 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -49,7 +49,6 @@ Set of functions that download and proce package Apache::loncoursedata; use strict; -use Apache::Constants qw(:common :http); use Apache::lonnet; use Apache::lonhtmlcommon; use Time::HiRes; @@ -66,30 +65,6 @@ and/or itself. =cut -sub LoadDiscussion { - my ($courseID)=@_; - my %Discuss=(); - my %contrib=&Apache::lonnet::dump( - $courseID, - $env{'course.'.$courseID.'.domain'}, - $env{'course.'.$courseID.'.num'}); - - #my %contrib=&DownloadCourseInformation($name, $courseID, 0); - - foreach my $temp(keys %contrib) { - if ($temp=~/^version/) { - my $ver=$contrib{$temp}; - my ($dummy,$prb)=split(':',$temp); - for (my $idx=1; $idx<=$ver; $idx++ ) { - my $name=$contrib{"$idx:$prb:sendername"}; - $Discuss{"$name:$prb"}=$idx; - } - } - } - - return \%Discuss; -} - ################################################ ################################################ @@ -869,7 +844,9 @@ sub populate_student_table { my $dbh = &Apache::lonmysql::get_dbh(); my $request = 'INSERT IGNORE INTO '.$student_table. "(student,section,status) VALUES "; - my $classlist = &get_classlist($courseid); + my $cdom = $env{'course.'.$courseid.'.domain'}; + my $cnum = $env{'course.'.$courseid.'.num'}; + my $classlist = &get_classlist($cdom,$cnum); my $student_count=0; while (my ($student,$data) = each %$classlist) { my ($section,$status) = ($data->[&CL_SECTION()], @@ -971,7 +948,7 @@ sub update_full_student_data { # # Download students data my $time_of_retrieval = time; - my @tmp = &Apache::lonnet::dump($courseid,$sdom,$sname); + my @tmp = &Apache::lonnet::dumpstore($courseid,$sdom,$sname); if (@tmp && $tmp[0] =~ /^error/) { $returnstatus = 'error retrieving full student data'; return $returnstatus; @@ -1214,7 +1191,7 @@ sub update_student_data { # # Set the students update time if ($Results[0] eq 'okay') { - &store_updatetime($student_id,$time_of_retrieval,$time_of_retrieval); + &store_updatetime($student_id,$time_of_retrieval); } # return @Results; @@ -1270,23 +1247,29 @@ sub store_student_data { # make sure the symb is set up properly my $symb_id = &get_symb_id($current_symb); # - # Load data into the tables + # Parameters while (my ($parameter,$value) = each(%$param_hash)) { - my $newstring; if ($parameter !~ /(timestamp|resource\.(.*)\.(solved|tries|awarded|award|awarddetail|previous))/) { - $newstring = "('".join("','", - $symb_id,$student_id, - $parameter)."',". - $dbh->quote($value)."),\n"; + my $sql_parameter = "('".join("','", + $symb_id,$student_id, + $parameter)."',". + $dbh->quote($value)."),\n"; $num_parameters ++; - if ($newstring !~ /''/) { - $store_parameters_command .= $newstring; - $rows_stored++; + if ($sql_parameter !~ /''/) { + $store_parameters_command .= $sql_parameter; + #$rows_stored++; } } - next if ($parameter !~ /^resource\.(.*)\.solved$/); - # + } + # Performance + my %stored; + while (my ($parameter,$value) = each(%$param_hash)) { + next if ($parameter !~ /^resource\.(.*)\.(solved|awarded)$/); my $part = $1; + next if ($part =~ /\./); + next if (exists($stored{$part})); + $stored{$part}++; + # my $part_id = &get_part_id($part); next if (!defined($part_id)); my $solved = $value; @@ -1301,29 +1284,31 @@ sub store_student_data { $awarded = '' if (! defined($awarded)); $award = '' if (! defined($award)); $awarddetail = '' if (! defined($awarddetail)); - $newstring = "('".join("','",$symb_id,$student_id,$part_id,$part, - $solved,$tries,$awarded,$award, - $awarddetail,$timestamp)."'),\n"; - $store_performance_command .= $newstring; + my $sql_performance = + "('".join("','",$symb_id,$student_id,$part_id,$part, + $solved,$tries,$awarded,$award, + $awarddetail,$timestamp)."'),\n"; + $store_performance_command .= $sql_performance; $rows_stored++; } } - chop $store_parameters_command; - chop $store_parameters_command; - chop $store_performance_command; - chop $store_performance_command; + if (! $rows_stored) { return ($returnstatus, undef); } + $store_parameters_command =~ s|,\n$||; + $store_performance_command =~ s|,\n$||; my $start = Time::HiRes::time; $dbh->do($store_performance_command); if ($dbh->err()) { - &Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); - &Apache::lonnet::logthis('command = '.$store_performance_command); + &Apache::lonnet::logthis('performance bigass insert error:'. + $dbh->errstr()); + &Apache::lonnet::logthis('command = '.$/.$store_performance_command); $returnstatus = 'error: unable to insert performance into database'; return ($returnstatus,$student_data); } $dbh->do($store_parameters_command) if ($num_parameters>0); if ($dbh->err()) { - &Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); - &Apache::lonnet::logthis('command = '.$store_parameters_command); + &Apache::lonnet::logthis('parameters bigass insert error:'. + $dbh->errstr()); + &Apache::lonnet::logthis('command = '.$/.$store_parameters_command); &Apache::lonnet::logthis('rows_stored = '.$rows_stored); &Apache::lonnet::logthis('student_id = '.$student_id); $returnstatus = 'error: unable to insert parameters into database'; @@ -1863,6 +1848,9 @@ sub execute_SQL_request { my ($dbh,$request)=@_; # &Apache::lonnet::logthis($request); my $sth = $dbh->prepare($request); + if (!$sth) { + die($dbh->errstr . " SQL: $request"); + } $sth->execute(); my $row = $sth->fetchrow_arrayref(); if (ref($row) eq 'ARRAY' && scalar(@$row)>0) { @@ -2020,9 +2008,17 @@ Inputs: $Sections: array ref of sections to include, $enrollment: string, $courseid (may be omitted) + $starttime (may be omitted) + $endtime (may be omitted) + $has_award_for (may be omitted) Returns; An array of arrays. The sub arrays contain a student name and -their score on the resources. +their score on the resources. $starttime and $endtime constrain the +list to awards obtained during the given time limits. $has_score_on +constrains the list to those students who at least attempted the +resource identified by the given symb, which is used to filter out +such students for statistics that would be adversely affected by such +students. =cut @@ -2032,7 +2028,7 @@ sub RNK_student { return 0; }; sub RNK_score { return 1; }; sub rank_students_by_scores_on_resources { - my ($resources,$Sections,$enrollment,$courseid,$starttime,$endtime) = @_; + my ($resources,$Sections,$enrollment,$courseid,$starttime,$endtime,$has_award_for) = @_; return if (! defined($resources) || ! ref($resources) eq 'ARRAY'); if (! defined($courseid)) { $courseid = $env{'request.course.id'}; @@ -2045,12 +2041,20 @@ sub rank_students_by_scores_on_resources my $symb_limits = '('.join(' OR ',map {'a.symb_id='.&get_symb_id($_); } @$resources ).')'; + my ($award_col, $award_join, $award_clause) = ('', '', ''); + if ($has_award_for) { + my $resource_id = &get_symb_id($has_award_for); + $award_col = ", perf.awarded"; + $award_join = "LEFT JOIN $performance_table AS perf ON perf.symb_id" + ." = $resource_id AND perf.student_id = b.student_id "; + $award_clause = "AND perf.awarded IS NOT NULL"; + } my $time_limits = &limit_by_start_end_time($starttime,$endtime,'a'); - my $request = 'SELECT b.student,SUM(a.awarded*w.weight) AS score FROM '. - $performance_table.' AS a '. - 'NATURAL LEFT JOIN '.$weight_table.' AS w '. - 'LEFT JOIN '.$student_table.' AS b ON a.student_id=b.student_id '. - 'WHERE '; + my $request = "SELECT b.student,SUM(a.awarded*w.weight) AS score " + ."$award_col FROM $performance_table AS a ". + "NATURAL LEFT JOIN $weight_table AS w ". + "LEFT JOIN $student_table AS b ON a.student_id=b.student_id ". + "$award_join WHERE "; if (defined($section_limits)) { $request .= $section_limits.' AND '; } @@ -2065,9 +2069,9 @@ sub rank_students_by_scores_on_resources } $request =~ s/( AND )$//; # Remove extra conjunction $request =~ s/( WHERE )$//; # In case there were no limits placed on it - $request .= ' GROUP BY a.student_id ORDER BY score'; + $request .= " $award_clause GROUP BY a.student_id ORDER BY score"; #&Apache::lonnet::logthis('request = '.$/.$request); - my $sth = $dbh->prepare($request); + my $sth = $dbh->prepare($request) or die "Can't prepare $request"; $sth->execute(); my $rows = $sth->fetchall_arrayref(); return ($rows); @@ -2202,7 +2206,7 @@ sub score_stats { # &Apache::lonnet::logthis('request = '.$/.$request); $request = 'SELECT SUM(weight) FROM '.$weight_table. - ' WHERE ('.$symb_restriction.')'; + ' AS a WHERE ('.$symb_restriction.')'; my ($max_possible) = &execute_SQL_request($dbh,$request); # &Apache::lonnet::logthis('request = '.$/.$request); return($min,$max,$ave,$std,$count,$max_possible); @@ -2251,11 +2255,10 @@ sub count_stats { $request = 'CREATE TEMPORARY TABLE '.$stats_table.' '. 'SELECT a.student_id,'. - 'COUNT(a.award) AS count FROM '. + 'SUM(a.awarded) AS count FROM '. $performance_table.' AS a '. 'LEFT JOIN '.$student_table.' AS b ON a.student_id=b.student_id '. - 'WHERE ('.$symb_restriction.')'. - " AND a.award!='INCORRECT_ATTEMPTED'"; + 'WHERE ('.$symb_restriction.')'; if ($time_limits) { $request .= ' AND '.$time_limits; } @@ -2690,9 +2693,9 @@ Retrieve the classist of a given class o information is returned from the classlist.db file and, if needed, from the students environment. -Optional arguments are $cid, $cdom, and $cnum (course id, course domain, -and course number, respectively). Any omitted arguments will be taken -from the current environment ($env{'request.course.id'}, +Optional arguments are $cdom, and $cnum (course domain, +and course number, respectively). If either is ommitted the course +will be taken from the current environment ($env{'request.course.id'}, $env{'course.'.$cid.'.domain'}, and $env{'course.'.$cid.'.num'}). Returns a reference to a hash which contains: @@ -2720,10 +2723,13 @@ sub CL_TYPE { return 8; } sub CL_LOCKEDTYPE { return 9; } sub get_classlist { - my ($cid,$cdom,$cnum) = @_; - $cid = $cid || $env{'request.course.id'}; - $cdom = $cdom || $env{'course.'.$cid.'.domain'}; - $cnum = $cnum || $env{'course.'.$cid.'.num'}; + my ($cdom,$cnum) = @_; + my $cid = $cdom.'_'.$cnum; + if (!defined($cdom) || !defined($cnum)) { + $cid = $env{'request.course.id'}; + $cdom = $env{'course.'.$cid.'.domain'}; + $cnum = $env{'course.'.$cid.'.num'}; + } my $now = time; # my %classlist=&Apache::lonnet::dump('classlist',$cdom,$cnum);