--- loncom/interface/loncoursedata.pm 2003/03/27 19:29:36 1.63 +++ loncom/interface/loncoursedata.pm 2003/06/02 16:57:41 1.73 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: loncoursedata.pm,v 1.63 2003/03/27 19:29:36 matthew Exp $ +# $Id: loncoursedata.pm,v 1.73 2003/06/02 16:57:41 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -104,7 +104,7 @@ sub get_sequence_assessment_data { my $fn=$ENV{'request.course.fn'}; ## ## use navmaps - my $navmap = Apache::lonnavmaps::navmap->new(Apache->request,$fn.".db", + my $navmap = Apache::lonnavmaps::navmap->new($fn.".db", $fn."_parms.db",1,0); if (!defined($navmap)) { return 'Can not open Coursemap'; @@ -137,8 +137,6 @@ sub get_sequence_assessment_data { # We need to keep track of which sequences contain homework problems # my $previous; - $curRes = $iterator->next(); # BEGIN_MAP - $curRes = $iterator->next(); # The first item in the top level map. while (scalar(@Nested_Sequences)) { $previous = $curRes; $curRes = $iterator->next(); @@ -211,6 +209,39 @@ sub LoadDiscussion { return \%Discuss; } +################################################ +################################################ + +=pod + +=item &GetUserName(username,userdomain) + +Returns a hash with the following entries: + 'firstname', 'middlename', 'lastname', 'generation', and 'fullname' + + 'fullname' is the result of &Apache::loncoursedata::ProcessFullName. + +=cut + +################################################ +################################################ +sub GetUserName { + my ($username,$userdomain) = @_; + $username = $ENV{'user.name'} if (! defined($username)); + $userdomain = $ENV{'user.domain'} if (! defined($username)); + my %userenv = &Apache::lonnet::get('environment', + ['firstname','middlename','lastname','generation'], + $userdomain,$username); + $userenv{'fullname'} = &ProcessFullName($userenv{'lastname'}, + $userenv{'generation'}, + $userenv{'firstname'}, + $userenv{'middlename'}); + return %userenv; +} + +################################################ +################################################ + =pod =item &ProcessFullName() @@ -221,6 +252,8 @@ is Lastname generation, firstname middle =cut +################################################ +################################################ sub ProcessFullName { my ($lastname, $generation, $firstname, $middlename)=@_; my $Str = ''; @@ -422,6 +455,13 @@ sub init_dbs { my $courseid = shift; &setup_table_names($courseid); # + # Drop any of the existing tables + foreach my $table ($symb_table,$part_table,$student_table, + $updatetime_table,$performance_table, + $parameters_table) { + &Apache::lonmysql::drop_table($table); + } + # # Note - changes to this table must be reflected in the code that # stores the data (calls &Apache::lonmysql::store_row with this table # id @@ -494,6 +534,9 @@ sub init_dbs { { name => 'part_id', type => 'MEDIUMINT UNSIGNED', restrictions => 'NOT NULL' }, + { name => 'part', + type => 'VARCHAR(100)', + restrictions => 'NOT NULL'}, { name => 'solved', type => 'TINYTEXT' }, { name => 'tries', @@ -581,6 +624,36 @@ sub init_dbs { =pod +=item &delete_caches() + +=cut + +################################################ +################################################ +sub delete_caches { + my $courseid = shift; + $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + # + &setup_table_names($courseid); + # + my $dbh = &Apache::lonmysql::get_dbh(); + foreach my $table ($symb_table,$part_table,$student_table, + $updatetime_table,$performance_table, + $parameters_table ){ + my $command = 'DROP TABLE '.$table.';'; + $dbh->do($command); + if ($dbh->err) { + &Apache::lonnet::logthis($command.' resulted in error: '.$dbh->errstr); + } + } + return; +} + +################################################ +################################################ + +=pod + =item &get_part_id() Get the MySQL id of a problem part string. @@ -862,7 +935,8 @@ sub update_student_data { if ($parameter !~ /(timestamp|resource\.(.*)\.(solved|tries|awarded|award|awarddetail|previous))/) { $newstring = "('".join("','", $symb_id,$student_id, - $parameter,$value)."'),\n"; + $parameter)."',". + $dbh->quote($value)."),\n"; $num_parameters ++; if ($newstring !~ /''/) { $store_parameters_command .= $newstring; @@ -886,7 +960,7 @@ sub update_student_data { $awarded = '' if (! defined($awarded)); $award = '' if (! defined($award)); $awarddetail = '' if (! defined($awarddetail)); - $newstring = "('".join("','",$symb_id,$student_id,$part_id, + $newstring = "('".join("','",$symb_id,$student_id,$part_id,$part, $solved,$tries,$awarded,$award, $awarddetail,$timestamp)."'),\n"; $store_performance_command .= $newstring; @@ -1030,21 +1104,21 @@ sub get_student_data_from_performance_ca # my $dbh = &Apache::lonmysql::get_dbh(); my $request = "SELECT ". - "d.symb,c.part,a.solved,a.tries,a.awarded,a.award,a.awarddetail,". + "d.symb,a.part,a.solved,a.tries,a.awarded,a.award,a.awarddetail,". "a.timestamp "; if (defined($student)) { $request .= "FROM $student_table AS b ". "LEFT JOIN $performance_table AS a ON b.student_id=a.student_id ". - "LEFT JOIN $part_table AS c ON c.part_id = a.part_id ". +# "LEFT JOIN $part_table AS c ON c.part_id = a.part_id ". "LEFT JOIN $symb_table AS d ON d.symb_id = a.symb_id ". "WHERE student='$student'"; if (defined($symb) && $symb ne '') { - $request .= " AND d.symb='".$dbh->quote($symb)."'"; + $request .= " AND d.symb=".$dbh->quote($symb); } } elsif (defined($symb) && $symb ne '') { $request .= "FROM $symb_table as d ". "LEFT JOIN $performance_table AS a ON d.symb_id=a.symb_id ". - "LEFT JOIN $part_table AS c ON c.part_id = a.part_id ". +# "LEFT JOIN $part_table AS c ON c.part_id = a.part_id ". "LEFT JOIN $student_table AS b ON b.student_id = a.student_id ". "WHERE symb='".$dbh->quote($symb)."'"; } @@ -1070,6 +1144,9 @@ sub get_student_data_from_performance_ca $studentdata->{$symb}->{$base.'.awarddetail'} = $awarddetail; $studentdata->{$symb}->{'timestamp'} = $time if (defined($time) && $time ne ''); } + if (defined($symb) && $symb ne '') { + $studentdata = $studentdata->{$symb}; + } return $studentdata; } @@ -1119,9 +1196,24 @@ sub get_current_state { return () if (! defined($sname) || ! defined($sdom)); # my ($status,$data) = &ensure_current_data($sname,$sdom,$courseid); + &Apache::lonnet::logthis + ('sname = '.$sname. + ' domain = '.$sdom. + ' status = '.$status. + ' data is '.(defined($data)?'defined':'undefined')); +# while (my ($symb,$hash) = each(%$data)) { +# &Apache::lonnet::logthis($symb."\n----------------------------------"); +# while (my ($key,$value) = each (%$hash)) { +# &Apache::lonnet::logthis(" ".$key." = ".$value); +# } +# } # if (defined($data)) { - return %$data; + if (defined($symb)) { + return %{$data->{$symb}}; + } else { + return %$data; + } } elsif ($status eq 'no data') { return (); } else { @@ -1150,6 +1242,47 @@ the students you are concerned with prio Inputs: $students, $symb, $part, $courseid +=over 4 + +=item $students is an array of hash references. +Each hash must contain at least the 'username' and 'domain' of a student. + +=item $symb is the symb for the problem. + +=item $part is the part id you need statistics for + +=item $courseid is the course id, of course! + +=back + +Outputs: See the code for up to date information. A hash reference is +returned. The hash has the following keys defined: + +=over 4 + +=item num_students The number of students attempting the problem + +=item tries The total number of tries for the students + +=item max_tries The maximum number of tries taken + +=item mean_tries The average number of tries + +=item num_solved The number of students able to solve the problem + +=item num_override The number of students whose answer is 'correct_by_override' + +=item deg_of_diff The degree of difficulty of the problem + +=item std_tries The standard deviation of the number of tries + +=item skew_tries The skew of the number of tries + +=item per_wrong The number of students attempting the problem who were not +able to answer it correctly. + +=back + =cut ################################################ @@ -1182,6 +1315,14 @@ sub get_problem_statistics { 'CREATE TEMPORARY TABLE '.$stats_table. ' SELECT student_id,solved,award,tries FROM '.$performance_table. ' WHERE symb_id='.$symb_id.' AND part_id='.$part_id; + if (defined($students)) { + $request .= ' AND ('. + join(' OR ', map {'student_id='. + &get_student_id($_->{'username'}, + $_->{'domain'}) + } @$students + ).')'; + } # &Apache::lonnet::logthis($request); $dbh->do($request); my ($num,$tries,$mod,$mean,$STD) = &execute_SQL_request @@ -1202,17 +1343,28 @@ sub get_problem_statistics { $solved = 0 if (! defined($solved)); # my $DegOfDiff = 'nan'; - $DegOfDiff = 1-($Solved + $solved)/$tries if ($tries>0); + $DegOfDiff = 1-($Solved)/$tries if ($tries>0); my $SKEW = 'nan'; + my $wrongpercent = 0; if ($num > 0) { ($SKEW) = &execute_SQL_request($dbh,'SELECT SQRT(SUM('. 'POWER(tries - '.$STD.',3)'. '))/'.$num.' FROM '.$stats_table); + $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; } # $dbh->do('DROP TABLE '.$stats_table); # May return an error - return ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD,$SKEW); + return { num_students => $num, + tries => $tries, + max_tries => $mod, + mean_tries => $mean, + std_tries => $STD, + skew_tries => $SKEW, + num_solved => $Solved, + num_override => $solved, + per_wrong => $wrongpercent, + deg_of_diff => $DegOfDiff } } sub execute_SQL_request {