version 1.143, 2005/03/01 00:07:20
|
version 1.145, 2005/03/07 20:12:08
|
Line 66 and/or itself.
|
Line 66 and/or itself.
|
|
|
=cut |
=cut |
|
|
#################################################### |
|
#################################################### |
|
|
|
=pod |
|
|
|
=item &get_sequence_assessment_data() |
|
|
|
Use lonnavmaps to build a data structure describing the order and |
|
assessment contents of each sequence in the current course. |
|
|
|
The returned structure is a hash reference. |
|
|
|
{ title => 'title', |
|
symb => 'symb', |
|
src => '/s/o/u/r/c/e', |
|
type => (container|assessment), |
|
num_assess => 2, # only for container |
|
parts => [11,13,15], # only for assessment |
|
response_ids => [12,14,16], # only for assessment |
|
contents => [........] # only for container |
|
} |
|
|
|
$hash->{'contents'} is a reference to an array of hashes of the same structure. |
|
|
|
Also returned are array references to the sequences and assessments contained |
|
in the course. |
|
|
|
|
|
=cut |
|
|
|
#################################################### |
|
#################################################### |
|
sub get_sequence_assessment_data { |
|
my $fn=$ENV{'request.course.fn'}; |
|
## |
|
## use navmaps |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (!defined($navmap)) { |
|
return 'Can not open Coursemap'; |
|
} |
|
# We explicity grab the top level map because I am not sure we |
|
# are pulling it from the iterator. |
|
my $top_level_map = $navmap->getById('0.0'); |
|
# |
|
my $iterator = $navmap->getIterator(undef, undef, undef, 1); |
|
my $curRes = $iterator->next(); # Top level sequence |
|
## |
|
## Prime the pump |
|
## |
|
## We are going to loop until we run out of sequences/pages to explore for |
|
## resources. This means we have to start out with something to look |
|
## at. |
|
my $title = $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; |
|
my $symb = $top_level_map->symb(); |
|
my $src = $top_level_map->src(); |
|
my $randompick = $top_level_map->randompick(); |
|
# |
|
my @Sequences; |
|
my @Assessments; |
|
my @Nested_Sequences = (); # Stack of sequences, keeps track of depth |
|
my $top = { title => $title, |
|
src => $src, |
|
symb => $symb, |
|
type => 'container', |
|
num_assess => 0, |
|
num_assess_parts => 0, |
|
contents => [], |
|
randompick => $randompick, |
|
}; |
|
push (@Sequences,$top); |
|
push (@Nested_Sequences, $top); |
|
# |
|
# We need to keep track of which sequences contain homework problems |
|
# |
|
my $previous_too; |
|
my $previous; |
|
while (scalar(@Nested_Sequences)) { |
|
$previous_too = $previous; |
|
$previous = $curRes; |
|
$curRes = $iterator->next(); |
|
my $currentmap = $Nested_Sequences[-1]; # Last one on the stack |
|
if ($curRes == $iterator->BEGIN_MAP()) { |
|
if (! ref($previous)) { |
|
$previous = $previous_too; |
|
} |
|
if (! ref($previous)) { |
|
next; |
|
} |
|
# get the map itself, instead of BEGIN_MAP |
|
$title = $previous->compTitle; |
|
$symb = $previous->symb(); |
|
$src = $previous->src(); |
|
$randompick = $previous->randompick(); |
|
my $newmap = { title => $title, |
|
src => $src, |
|
symb => $symb, |
|
type => 'container', |
|
num_assess => 0, |
|
randompick => $randompick, |
|
contents => [], |
|
}; |
|
push (@{$currentmap->{'contents'}},$newmap); # this is permanent |
|
push (@Sequences,$newmap); |
|
push (@Nested_Sequences, $newmap); # this is a stack |
|
next; |
|
} |
|
if ($curRes == $iterator->END_MAP()) { |
|
pop(@Nested_Sequences); |
|
next; |
|
} |
|
next if (! ref($curRes)); |
|
next if (! $curRes->is_problem() && $curRes->src() !~ /\.survey$/); |
|
# Okay, from here on out we only deal with assessments |
|
$title = $curRes->compTitle(); |
|
$symb = $curRes->symb(); |
|
$src = $curRes->src(); |
|
my $parts = $curRes->parts(); |
|
my %partdata; |
|
foreach my $part (@$parts) { |
|
my @Responses = $curRes->responseType($part); |
|
my @Ids = $curRes->responseIds($part); |
|
$partdata{$part}->{'ResponseTypes'}= \@Responses; |
|
$partdata{$part}->{'ResponseIds'} = \@Ids; |
|
$partdata{$part}->{'Survey'} = $curRes->is_survey($part); |
|
# Count how many responses of each type there are in this part |
|
foreach (@Responses) { |
|
$partdata{$part}->{$_}++; |
|
} |
|
} |
|
my $assessment = { title => $title, |
|
src => $src, |
|
symb => $symb, |
|
type => 'assessment', |
|
parts => $parts, |
|
num_parts => scalar(@$parts), |
|
partdata => \%partdata, |
|
}; |
|
push(@Assessments,$assessment); |
|
push(@{$currentmap->{'contents'}},$assessment); |
|
$currentmap->{'num_assess'}++; |
|
$currentmap->{'num_assess_parts'}+= scalar(@$parts); |
|
} |
|
return ($top,\@Sequences,\@Assessments); |
|
} |
|
|
|
sub LoadDiscussion { |
sub LoadDiscussion { |
my ($courseID)=@_; |
my ($courseID)=@_; |
my %Discuss=(); |
my %Discuss=(); |
Line 777 sub init_dbs {
|
Line 632 sub init_dbs {
|
|
|
=item &delete_caches() |
=item &delete_caches() |
|
|
|
This routine drops all the tables associated with a course from the |
|
MySQL database. |
|
|
|
Input: course id (optional, determined by environment if omitted) |
|
|
|
Returns: nothing |
|
|
=cut |
=cut |
|
|
################################################ |
################################################ |
Line 1058 sub clear_internal_caches {
|
Line 920 sub clear_internal_caches {
|
undef(%students_by_id); |
undef(%students_by_id); |
} |
} |
|
|
|
|
################################################ |
################################################ |
################################################ |
################################################ |
|
|
Line 2028 sub populate_weight_table {
|
Line 1889 sub populate_weight_table {
|
} |
} |
# |
# |
&setup_table_names($courseid); |
&setup_table_names($courseid); |
my ($top,$sequences,$assessments) = get_sequence_assessment_data(); |
my $navmap = Apache::lonnavmaps::navmap->new(); |
if (! defined($top) || ! ref($top)) { |
if (!defined($navmap)) { |
# There has been an error, better report it |
&Apache::lonnet::logthis('loncoursedata::populate_weight_table:'.$/. |
&Apache::lonnet::logthis('top is undefined'); |
' unable to get navmaps resource'.$/. |
|
' '.join(' ',(caller))); |
|
return; |
|
} |
|
my @sequences = $navmap->retrieveResources(undef, |
|
sub { shift->is_map(); },1,0,1); |
|
my @resources; |
|
foreach my $seq (@sequences) { |
|
push(@resources,$navmap->retrieveResources($seq, |
|
sub {shift->is_problem();}, |
|
0,0,0)); |
|
} |
|
if (! scalar(@resources)) { |
|
&Apache::lonnet::logthis('loncoursedata::populate_weight_table:'.$/. |
|
' no resources returned for '.$courseid); |
return; |
return; |
} |
} |
# Since we use lonnet::EXT to retrieve problem weights, |
# Since we use lonnet::EXT to retrieve problem weights, |
Line 2041 sub populate_weight_table {
|
Line 1916 sub populate_weight_table {
|
my $request = 'INSERT IGNORE INTO '.$weight_table. |
my $request = 'INSERT IGNORE INTO '.$weight_table. |
"(symb_id,part_id,weight) VALUES "; |
"(symb_id,part_id,weight) VALUES "; |
my $weight; |
my $weight; |
foreach my $res (@$assessments) { |
foreach my $res (@resources) { |
my $symb_id = &get_symb_id($res->{'symb'}); |
my $symb_id = &get_symb_id($res->symb); |
foreach my $part (@{$res->{'parts'}}) { |
foreach my $part (@{$res->parts}) { |
my $part_id = &get_part_id($part); |
my $part_id = &get_part_id($part); |
$weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', |
$weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', |
$res->{'symb'}, |
$res->symb, |
undef,undef,undef); |
undef,undef,undef); |
if (!defined($weight) || ($weight eq '')) { |
if (!defined($weight) || ($weight eq '')) { |
$weight=1; |
$weight=1; |
Line 2651 sub get_response_time_data {
|
Line 2526 sub get_response_time_data {
|
################################################ |
################################################ |
################################################ |
################################################ |
sub get_student_scores { |
sub get_student_scores { |
my ($Sections,$Symbs,$enrollment,$courseid,$starttime,$endtime) = @_; |
my ($sections,$Symbs,$enrollment,$courseid,$starttime,$endtime) = @_; |
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
&setup_table_names($courseid); |
&setup_table_names($courseid); |
my $dbh = &Apache::lonmysql::get_dbh(); |
my $dbh = &Apache::lonmysql::get_dbh(); |
return (undef) if (! defined($dbh)); |
return (undef) if (! defined($dbh)); |
my $tmptable = $courseid.'_temp_'.time; |
my $tmptable = $courseid.'_temp_'.time; |
|
my $request = 'DROP TABLE IF EXISTS '.$tmptable; |
|
# &Apache::lonnet::logthis('request = '.$/.$request); |
|
$dbh->do($request); |
# |
# |
my $symb_requirements; |
my $symb_requirements; |
if (defined($Symbs) && @$Symbs) { |
if (defined($Symbs) && @$Symbs) { |
Line 2667 sub get_student_scores {
|
Line 2545 sub get_student_scores {
|
} @$Symbs).')'; |
} @$Symbs).')'; |
} |
} |
# |
# |
my $student_requirements; |
my ($student_requirements,$enrollment_requirements) = |
if ( (defined($Sections) && $Sections->[0] ne 'all')) { |
&limit_by_section_and_status($sections,$enrollment,'b'); |
$student_requirements = '('. |
|
join(' OR ', map { "b.section='".$_."'" } @$Sections |
|
).')'; |
|
} |
|
# |
|
my $enrollment_requirements=undef; |
|
if (defined($enrollment) && $enrollment ne 'Any') { |
|
$enrollment_requirements = "b.status='".$enrollment."'"; |
|
} |
|
# |
# |
my $time_requirements = undef; |
my $time_requirements = &limit_by_start_end_time($starttime,$endtime,'a'); |
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. |
$request = 'CREATE TEMPORARY TABLE IF NOT EXISTS '.$tmptable. |
' SELECT a.student_id,SUM(a.awarded) AS score FROM '. |
' SELECT a.student_id,SUM(a.awarded*c.weight) AS score FROM '. |
$performance_table.' AS a '; |
$performance_table.' AS a '; |
|
$request .= "LEFT JOIN ".$weight_table.' AS c ON a.symb_id=c.symb_id AND a.part_id=c.part_id '; |
if (defined($student_requirements) || defined($enrollment_requirements)) { |
if (defined($student_requirements) || defined($enrollment_requirements)) { |
$request .= ' NATURAL LEFT JOIN '.$student_table.' AS b '; |
$request .= ' LEFT JOIN '.$student_table.' AS b ON a.student_id=b.student_id'; |
} |
} |
if (defined($symb_requirements) || |
if (defined($symb_requirements) || |
defined($student_requirements) || |
defined($student_requirements) || |