Diff for /loncom/interface/loncoursedata.pm between versions 1.126 and 1.127

version 1.126, 2004/03/22 17:25:26 version 1.127, 2004/03/23 16:35:15
Line 475  about both the response and part data. Line 475  about both the response and part data.
 'transaction', and 'timestamp'.    'transaction', and 'timestamp'.  
 The primary key is based on the first 3 columns.  The primary key is based on the first 3 columns.
   
   =item $weight_table
   
   The weight table holds the weight for the problems used in the class.
   Whereas the weight of a problem can vary by section and student the data
   here is applied to the class as a whole.
   Columns: 'symb_id','part_id','response_id','weight'.
   
 =back  =back
   
 =back  =back
Line 518  my $parameters_table; Line 525  my $parameters_table;
 my $fulldump_response_table;  my $fulldump_response_table;
 my $fulldump_part_table;  my $fulldump_part_table;
 my $fulldump_timestamp_table;  my $fulldump_timestamp_table;
   my $weight_table;
   
 my @Tables;  my @Tables;
 ################################################  ################################################
Line 628  sub init_dbs { Line 636  sub init_dbs {
                     { name => 'tries',                      { name => 'tries',
                       type => 'SMALLINT UNSIGNED' },                        type => 'SMALLINT UNSIGNED' },
                     { name => 'awarded',                      { name => 'awarded',
                       type => 'TINYTEXT' },                        type => 'REAL' },
                     { name => 'award',                      { name => 'award',
                       type => 'TINYTEXT' },                        type => 'TINYTEXT' },
                     { name => 'awarddetail',                      { name => 'awarddetail',
Line 663  sub init_dbs { Line 671  sub init_dbs {
                     { name => 'award',                      { name => 'award',
                       type => 'TINYTEXT' },                        type => 'TINYTEXT' },
                     { name => 'awarded',                      { name => 'awarded',
                       type => 'TINYTEXT' },                        type => 'REAL' },
                     { name => 'previous',                      { name => 'previous',
                       type => 'SMALLINT UNSIGNED' },                        type => 'SMALLINT UNSIGNED' },
 #                    { name => 'regrader',  #                    { name => 'regrader',
Line 740  sub init_dbs { Line 748  sub init_dbs {
                   { columns=>['transaction'] },                    { columns=>['transaction'] },
                   ],                    ],
     };      };
   
     #      #
     my $parameters_table_def = {      my $parameters_table_def = {
         id => $parameters_table,          id => $parameters_table,
Line 760  sub init_dbs { Line 767  sub init_dbs {
         'PRIMARY KEY' => ['symb_id','student_id','parameter (255)'],          'PRIMARY KEY' => ['symb_id','student_id','parameter (255)'],
     };      };
     #      #
       my $weight_table_def = {
           id => $weight_table,
           permanent => 'no',
           columns => [{ name => 'symb_id',
                         type => 'MEDIUMINT UNSIGNED',
                         restrictions => 'NOT NULL'  },
                       { name => 'part_id',
                         type => 'MEDIUMINT UNSIGNED',
                         restrictions => 'NOT NULL'  },
                       { name => 'weight',
                         type => 'REAL',
                         restrictions => 'NOT NULL'  },
                       ],
           'PRIMARY KEY' => ['symb_id','part_id'],
       };
       #
     # Create the tables      # Create the tables
     my $tableid;      my $tableid;
     $tableid = &Apache::lonmysql::create_table($symb_table_def);      $tableid = &Apache::lonmysql::create_table($symb_table_def);
Line 816  sub init_dbs { Line 839  sub init_dbs {
                                  &Apache::lonmysql::get_error());                                   &Apache::lonmysql::get_error());
         return 9;          return 9;
     }      }
       $tableid = &Apache::lonmysql::create_table($weight_table_def);
       if (! defined($tableid)) {
           &Apache::lonnet::logthis("error creating weight_table: ".
                                    &Apache::lonmysql::get_error());
           return 10;
       }
     return 0;      return 0;
 }  }
   
Line 1077  sub populate_student_table { Line 1106  sub populate_student_table {
     return;      return;
 }  }
   
   
 ################################################  ################################################
 ################################################  ################################################
   
Line 1548  sub ensure_tables_are_set_up { Line 1576  sub ensure_tables_are_set_up {
     my @CurrentTable = &Apache::lonmysql::tables_in_db();      my @CurrentTable = &Apache::lonmysql::tables_in_db();
     my ($found_symb,$found_student,$found_part,      my ($found_symb,$found_student,$found_part,
         $found_performance,$found_parameters,$found_fulldump_part,          $found_performance,$found_parameters,$found_fulldump_part,
         $found_fulldump_response,$found_fulldump_timestamp);          $found_fulldump_response,$found_fulldump_timestamp,
           $found_weight);
     foreach (@CurrentTable) {      foreach (@CurrentTable) {
         $found_symb        = 1 if ($_ eq $symb_table);          $found_symb        = 1 if ($_ eq $symb_table);
         $found_student     = 1 if ($_ eq $student_table);          $found_student     = 1 if ($_ eq $student_table);
Line 1558  sub ensure_tables_are_set_up { Line 1587  sub ensure_tables_are_set_up {
         $found_fulldump_part      = 1 if ($_ eq $fulldump_part_table);          $found_fulldump_part      = 1 if ($_ eq $fulldump_part_table);
         $found_fulldump_response  = 1 if ($_ eq $fulldump_response_table);          $found_fulldump_response  = 1 if ($_ eq $fulldump_response_table);
         $found_fulldump_timestamp = 1 if ($_ eq $fulldump_timestamp_table);          $found_fulldump_timestamp = 1 if ($_ eq $fulldump_timestamp_table);
           $found_weight      = 1 if ($_ eq $weight_table);
     }      }
     if (!$found_symb        ||       if (!$found_symb          || 
         !$found_student     || !$found_part   ||          !$found_student       || !$found_part              ||
         !$found_performance || !$found_parameters ||          !$found_performance   || !$found_parameters        ||
         !$found_fulldump_part || !$found_fulldump_response ||          !$found_fulldump_part || !$found_fulldump_response ||
         !$found_fulldump_timestamp ) {          !$found_fulldump_timestamp || !$found_weight ) {
         if (&init_dbs($courseid)) {          if (&init_dbs($courseid)) {
             return 'error';              return 'error';
         }          }
Line 2035  sub get_problem_statistics { Line 2065  sub get_problem_statistics {
              deg_of_diff  => $DegOfDiff };               deg_of_diff  => $DegOfDiff };
 }  }
   
   ##
   ## This is a helper for get_statistics
 sub execute_SQL_request {  sub execute_SQL_request {
     my ($dbh,$request)=@_;      my ($dbh,$request)=@_;
 #    &Apache::lonnet::logthis($request);  #    &Apache::lonnet::logthis($request);
Line 2047  sub execute_SQL_request { Line 2079  sub execute_SQL_request {
     return ();      return ();
 }  }
   
   ######################################################
   ######################################################
   
   =pod
   
   =item &populate_weight_table
   
   =cut
   
   ######################################################
   ######################################################
   sub populate_weight_table {
       my ($courseid) = @_;
       if (! defined($courseid)) {
           $courseid = $ENV{'request.course.id'};
       }
       #
       &setup_table_names($courseid);
       my ($top,$sequences,$assessments) = get_sequence_assessment_data();
       if (! defined($top) || ! ref($top)) {
           # There has been an error, better report it
           &Apache::lonnet::logthis('top is undefined');
           return;
       }
       #       Since we use lonnet::EXT to retrieve problem weights,
       #       to ensure current data we must clear the caches out.
       &Apache::lonnet::clear_EXT_cache_status();
       my $dbh = &Apache::lonmysql::get_dbh();
       my $request = 'INSERT IGNORE INTO '.$weight_table.
           "(symb_id,part_id,weight) VALUES ";
       my $weight;
       foreach my $res (@$assessments) {
           my $symb_id = &get_symb_id($res->{'symb'});
           foreach my $part (@{$res->{'parts'}}) {
               my $part_id = &get_part_id($part);
               $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',
                                              $res->{'symb'},
                                              undef,undef,undef);
               if (!defined($weight) || ($weight eq '')) { 
                   $weight=1;
               }
               $request .= "('".$symb_id."','".$part_id."','".$weight."'),";
           }
       }
       $request =~ s/(,)$//;
   #    &Apache::lonnet::logthis('request = '.$/.$request);
       $dbh->do($request);
       if ($dbh->err()) {
           &Apache::lonnet::logthis("error ".$dbh->errstr().
                                    " occured executing \n".
                                    $request);
       }
       return;
   }
   
   ##########################################################
   ##########################################################
   
   =pod
   
   =item &limit_by_section_and_status
   
   Build SQL WHERE condition which limits the data collected by section and
   student status.
   
   Inputs: $Sections (array ref)
       $enrollment (string: 'any', 'expired', 'active')
       $tablename The name of the table that holds the student data
   
   Returns: $student_requirements,$enrollment_requirements
   
   =cut
   
   ##########################################################
   ##########################################################
   sub limit_by_section_and_status {
       my ($Sections,$enrollment,$tablename) = @_;
       my $student_requirements = undef;
       if ( (defined($Sections) && $Sections->[0] ne 'all')) {
           $student_requirements = '('.
               join(' OR ', map { $tablename.".section='".$_."'" } @$Sections
                    ).')';
       }
       #
       my $enrollment_requirements=undef;
       if (defined($enrollment) && $enrollment ne 'Any') {
           $enrollment_requirements = $tablename.".status='".$enrollment."'";
       }
       return ($student_requirements,$enrollment_requirements);
   }
   
   ######################################################
   ######################################################
   
   =pod
   
   =item rank_students_by_scores_on_resources
   
   Inputs: 
       $resources: array ref of hash ref.  Each hash ref needs key 'symb'.
       $Sections: array ref of sections to include,
       $enrollment: string,
       $courseid (may be omitted)
   
   Returns; An array of arrays.  The sub arrays contain a student name and
   their score on the resources.
   
   =cut
   
   ######################################################
   ######################################################
   sub RNK_student { return 0; };
   sub RNK_score   { return 1; };
   
   sub rank_students_by_scores_on_resources {
       my ($resources,$Sections,$enrollment,$courseid) = @_;
       return if (! defined($resources) || ! ref($resources) eq 'ARRAY');
       if (! defined($courseid)) {
           $courseid = $ENV{'request.course.id'};
       }
       #
       &setup_table_names($courseid);
       my $dbh = &Apache::lonmysql::get_dbh();
       my ($section_limits,$enrollment_limits)=
           &limit_by_section_and_status($Sections,$enrollment,'b');
       my $symb_limits = '('.join(' OR ',map {'a.symb_id='.&get_symb_id($_);
                                          } @$resources
                                  ).')';
       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 ';
       if (defined($section_limits)) {
           $request .= $section_limits.' AND ';
       }
       if (defined($enrollment_limits)) {
           $request .= $enrollment_limits.' AND ';
       }
       if ($symb_limits ne '()') {
           $request .= $symb_limits.' AND ';
       }
       $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';
       #&Apache::lonnet::logthis('request = '.$/.$request);
       my $sth = $dbh->prepare($request);
       $sth->execute();
       my $rows = $sth->fetchall_arrayref();
       return ($rows);
   }
   
   ########################################################
   ########################################################
   
   =pod
   
   =item &get_sum_of_scores
   
   Inputs: $resource (hash ref, needs {'symb'} key),
   $part, (the part id),
   $students (array ref, contents of array are scalars holding 'sname:sdom'),
   $courseid
   
   Returns: the sum of the score on the problem part over the students and the
      maximum possible value for the sum (taken from the weight table).
   
   =cut
   
   ########################################################
   ########################################################
   sub get_sum_of_scores {
       my ($resource,$part,$students,$courseid) = @_;
       if (! defined($courseid)) {
           $courseid = $ENV{'request.course.id'};
       }
       #
       &setup_table_names($courseid);
       my $dbh = &Apache::lonmysql::get_dbh();
       my $request = 'SELECT SUM(a.awarded*w.weight),SUM(w.weight) FROM '.
           $performance_table.' AS a '.
           'NATURAL LEFT JOIN '.$weight_table.' AS w ';
       $request .= 'WHERE a.symb_id='.&get_symb_id($resource->{'symb'}).
           ' AND a.part_id='.&get_part_id($part);
       if (defined($students)) {
           $request .= ' AND ('.
               join(' OR ',map {'a.student_id='.&get_student_id(split(':',$_));
                            } @$students).
                                ')';
       }
       my $sth = $dbh->prepare($request);
       $sth->execute();
       my $rows = $sth->fetchrow_arrayref();
       if ($dbh->err) {
           &Apache::lonnet::logthis('error = '.$dbh->errstr());
           return (undef,undef);
       }
       return ($rows->[0],$rows->[1]);
   }
   
   
   ######################################################
   ######################################################
   
   =pod
   
   =item get_student_data
   
   =cut
   
   ######################################################
   ######################################################
 sub get_student_data {  sub get_student_data {
     my ($students,$courseid) = @_;      my ($students,$courseid) = @_;
     $courseid = $ENV{'request.course.id'} if (! defined($courseid));      $courseid = $ENV{'request.course.id'} if (! defined($courseid));
Line 2099  sub get_response_data { Line 2342  sub get_response_data {
     my $dbh = &Apache::lonmysql::get_dbh();      my $dbh = &Apache::lonmysql::get_dbh();
     return undef if (! defined($dbh));      return undef if (! defined($dbh));
     #      #
     my $student_requirements;      my ($student_requirements,$enrollment_requirements) = 
     if ( (defined($Sections) && $Sections->[0] ne 'all')) {          &limit_by_section_and_status($Sections,$enrollment,'d');
         $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 '.      my $request = 'SELECT '.
         'a.student_id, a.awarddetail, a.response_specific_value, '.          'a.student_id, a.awarddetail, a.response_specific_value, '.
         'a.submission, b.timestamp, c.tries, d.student '.          'a.submission, b.timestamp, c.tries, d.student '.
Line 2400  sub setup_table_names { Line 2634  sub setup_table_names {
     $fulldump_part_table      = $base_id.'_'.'partdata';      $fulldump_part_table      = $base_id.'_'.'partdata';
     $fulldump_response_table  = $base_id.'_'.'responsedata';      $fulldump_response_table  = $base_id.'_'.'responsedata';
     $fulldump_timestamp_table = $base_id.'_'.'timestampdata';      $fulldump_timestamp_table = $base_id.'_'.'timestampdata';
       $weight_table             = $base_id.'_'.'weight';
     #      #
     @Tables = (      @Tables = (
                $symb_table,                 $symb_table,
Line 2410  sub setup_table_names { Line 2645  sub setup_table_names {
                $fulldump_part_table,                 $fulldump_part_table,
                $fulldump_response_table,                 $fulldump_response_table,
                $fulldump_timestamp_table,                 $fulldump_timestamp_table,
                  $weight_table,
                );                 );
     return;      return;
 }  }

Removed from v.1.126  
changed lines
  Added in v.1.127


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