--- loncom/homework/grades.pm 2003/07/17 22:08:25 1.118
+++ loncom/homework/grades.pm 2007/09/07 00:07:30 1.439
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.118 2003/07/17 22:08:25 ng Exp $
+# $Id: grades.pm,v 1.439 2007/09/07 00:07:30 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,15 +25,6 @@
#
# http://www.lon-capa.org/
#
-# 2/9,2/13 Guy Albertelli
-# 6/8 Gerd Kortemeyer
-# 7/26 H.K. Ng
-# 8/20 Gerd Kortemeyer
-# Year 2002
-# June-August H.K. Ng
-# Year 2003
-# February, March H.K. Ng
-#
package Apache::grades;
use strict;
@@ -45,116 +36,320 @@ use Apache::lonhtmlcommon;
use Apache::lonnavmaps;
use Apache::lonhomework;
use Apache::loncoursedata;
-use Apache::lonmsg qw(:user_normal_msg);
+use Apache::lonmsg();
use Apache::Constants qw(:common);
+use Apache::lonlocal;
+use Apache::lonenc;
use String::Similarity;
+use LONCAPA;
+
+use POSIX qw(floor);
+
-my %oldessays=();
my %perm=();
+my %bubble_lines_per_response; # no. bubble lines for each response.
+ # index is "symb.part_id"
+
# ----- These first few routines are general use routines.----
#
-# --- Retrieve the parts that matches stores_\d+ from the metadata file.---
+# --- Retrieve the parts from the metadata file.---
sub getpartlist {
- my ($url) = @_;
- my @parts =();
- my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys'));
- foreach my $key (@metakeys) {
- if ( $key =~ m/stores_(\w+)_.*/) {
- push(@parts,$key);
+ my ($symb) = @_;
+
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ my $res = $navmap->getBySymb($symb);
+ my $partlist = $res->parts();
+ my $url = $res->src();
+ my @metakeys = split(/,/,&Apache::lonnet::metadata($url,'keys'));
+
+ my @stores;
+ foreach my $part (@{ $partlist }) {
+ foreach my $key (@metakeys) {
+ if ($key =~ m/^stores_\Q$part\E_/) { push(@stores,$key); }
}
}
- return @parts;
+ return @stores;
}
# --- Get the symbolic name of a problem and the url
-sub get_symb_and_url {
- my ($request) = @_;
- (my $url=$ENV{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
- my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
- if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
- return ($symb,$url);
-}
-
-# --- Retrieve the fullname for a user. Return lastname, first middle ---
-# --- Generation is attached next to the lastname if it exists. ---
-sub get_fullname {
- my ($uname,$udom) = @_;
- my %name=&Apache::lonnet::get('environment', ['lastname','generation',
- 'firstname','middlename'],
- $udom,$uname);
- my $fullname;
- my ($tmp) = keys(%name);
- if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
- $fullname = &Apache::loncoursedata::ProcessFullName
- (@name{qw/lastname generation firstname middlename/});
+sub get_symb {
+ my ($request,$silent) = @_;
+ (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
+ my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url)));
+ if ($symb eq '') {
+ if (!$silent) {
+ $request->print("Unable to handle ambiguous references:$url:.");
+ return ();
+ }
+ }
+ &Apache::lonenc::check_decrypt(\$symb);
+ return ($symb);
+}
+
+#--- Format fullname, username:domain if different for display
+#--- Use anywhere where the student names are listed
+sub nameUserString {
+ my ($type,$fullname,$uname,$udom) = @_;
+ if ($type eq 'header') {
+ return ' Fullname (Username)';
} else {
- &Apache::lonnet::logthis('grades.pm: no name data for '.$uname.
- '@'.$udom.':'.$tmp);
+ return ' '.$fullname.' ('.$uname.
+ ($env{'user.domain'} eq $udom ? '' : ' ('.$udom.')').')';
}
- return $fullname;
}
#--- Get the partlist and the response type for a given problem. ---
#--- Indicate if a response type is coded handgraded or not. ---
sub response_type {
- my ($url) = shift;
- my $allkeys = &Apache::lonnet::metadata($url,'keys');
- my %seen = ();
- my (@partlist,%handgrade);
- foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) {
- if (/^\w+response_\w+.*/) {
- my ($responsetype,$part) = split(/_/,$_,2);
- my ($partid,$respid) = split(/_/,$part);
- $responsetype =~ s/response$//; # make it compatible w/ navmaps - should move to that!!
- $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no');
- next if ($seen{$partid} > 0);
- $seen{$partid}++;
- push @partlist,$partid;
- }
+ my ($symb) = shift;
+
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ my $res = $navmap->getBySymb($symb);
+ my $partlist = $res->parts();
+ my %vPart =
+ map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart'));
+ my (%response_types,%handgrade);
+ foreach my $part (@{ $partlist }) {
+ next if (%vPart && !exists($vPart{$part}));
+
+ my @types = $res->responseType($part);
+ my @ids = $res->responseIds($part);
+ for (my $i=0; $i < scalar(@ids); $i++) {
+ $response_types{$part}{$ids[$i]} = $types[$i];
+ $handgrade{$part.'_'.$ids[$i]} =
+ &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i].
+ '.handgrade',$symb);
+ }
+ }
+ return ($partlist,\%handgrade,\%response_types);
+}
+
+sub flatten_responseType {
+ my ($responseType) = @_;
+ my @part_response_id =
+ map {
+ my $part = $_;
+ map {
+ [$part,$_]
+ } sort(keys(%{ $responseType->{$part} }));
+ } sort(keys(%$responseType));
+ return @part_response_id;
+}
+
+sub get_display_part {
+ my ($partID,$symb)=@_;
+ my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display',$symb);
+ if (defined($display) and $display ne '') {
+ $display.= " (id $partID)";
+ } else {
+ $display=$partID;
}
- return \@partlist,\%handgrade;
+ return $display;
}
#--- Show resource title
#--- and parts and response type
sub showResourceInfo {
- my ($url,$probTitle) = @_;
- my $result ='
'.
- '
Current Resource: '.$probTitle.'
'."\n";
- my ($partlist,$handgrade) = &response_type($url);
- my ($resptype,$hdgrade)=('','no');
- for (sort keys(%$handgrade)) {
- my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
- $resptype = $responsetype;
- $hdgrade = $handgrade if ($handgrade eq 'yes');
- $result.='
Part '.(split(/_/))[0].'
'.
- '
Type: '.$responsetype.'
';
+ my ($symb,$probTitle,$checkboxes) = @_;
+ my $col=3;
+ if ($checkboxes) { $col=4; }
+ my $result = '
'.&mt('Current Resource').': '.$probTitle.'
'."\n";
+ $result .='
';
+ my ($partlist,$handgrade,$responseType) = &response_type($symb);
+ my %resptype = ();
+ my $hdgrade='no';
+ my %partsseen;
+ foreach my $partID (sort keys(%$responseType)) {
+ foreach my $resID (sort keys(%{ $responseType->{$partID} })) {
+ my $handgrade=$$handgrade{$partID.'_'.$resID};
+ my $responsetype = $responseType->{$partID}->{$resID};
+ $hdgrade = $handgrade if ($handgrade eq 'yes');
+ $result.='
';
+ if ($checkboxes) {
+ if (exists($partsseen{$partID})) {
+ $result.="
';
+ my @grade = grep(/^\Q${version}resource.$respid.$partid.\E[^.]*[.]status$/,
+ keys(%{$record}));
+ foreach my $grade (sort(@grade)) {
+ my ($dim) = ($grade =~/[.]([^.]+)[.]status$/);
+ $result.= '
'.&mt("Dimension: [_1], status [_2] ",
+ $dim, $record->{$grade}).
+ '
';
+ }
+ $result.='
';
+ return $result;
+ }
+
}
return $answer;
}
@@ -187,7 +382,8 @@ sub commonJSfunctions {
}
}
} else {
- if (selectOne.selected) return selectOne.value;
+ // only one value it must be the selected one
+ return selectOne.value;
}
}
@@ -198,33 +394,52 @@ COMMONJSFUNCTIONS
#--- section, ids and fullnames for each user.
sub getclasslist {
my ($getsec,$filterlist) = @_;
+ my @getsec;
+ if (!ref($getsec)) {
+ if ($getsec ne '' && $getsec ne 'all') {
+ @getsec=($getsec);
+ }
+ } else {
+ @getsec=@{$getsec};
+ }
+ if (grep(/^all$/,@getsec)) { undef(@getsec); }
+
my $classlist=&Apache::loncoursedata::get_classlist();
# Bail out if we were unable to get the classlist
return if (! defined($classlist));
#
my %sections;
my %fullnames;
- foreach (keys(%$classlist)) {
- # the following undefs are for 'domain', and 'username' respectively.
- my (undef,undef,$end,$start,$id,$section,$fullname,$status)=
- @{$classlist->{$_}};
+ foreach my $student (keys(%$classlist)) {
+ my $end =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_END()];
+ my $start =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_START()];
+ my $id =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_ID()];
+ my $section =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_SECTION()];
+ my $fullname =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_FULLNAME()];
+ my $status =
+ $classlist->{$student}->[&Apache::loncoursedata::CL_STATUS()];
# filter students according to status selected
- if ($filterlist && $ENV{'form.Status'} ne 'Any') {
- if ($ENV{'form.Status'} ne $status) {
- delete ($classlist->{$_});
+ if ($filterlist && $env{'form.Status'} ne 'Any') {
+ if ($env{'form.Status'} ne $status) {
+ delete ($classlist->{$student});
next;
}
}
- $section = ($section ne '' ? $section : 'no');
+ $section = ($section ne '' ? $section : 'none');
if (&canview($section)) {
- if ($getsec eq 'all' || $getsec eq $section) {
+ if (!@getsec || grep(/^\Q$section\E$/,@getsec)) {
$sections{$section}++;
- $fullnames{$_}=$fullname;
+ $fullnames{$student}=$fullname;
} else {
- delete($classlist->{$_});
+ delete($classlist->{$student});
}
} else {
- delete($classlist->{$_});
+ delete($classlist->{$student});
}
}
my %seen = ();
@@ -274,11 +489,11 @@ sub canview {
#--- Retrieve the grade status of a student for all the parts
sub student_gradeStatus {
- my ($url,$symb,$udom,$uname,$partlist) = @_;
- my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
+ my ($symb,$udom,$uname,$partlist) = @_;
+ my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
my %partstatus = ();
foreach (@$partlist) {
- my ($status,$foo) = split(/_/,$record{"resource.$_.solved"},2);
+ my ($status,undef) = split(/_/,$record{"resource.$_.solved"},2);
$status = 'nothing' if ($status eq '');
$partstatus{$_} = $status;
my $subkey = "resource.$_.submitted_by";
@@ -291,7 +506,7 @@ sub student_gradeStatus {
# Use by verifyscript and viewgrades
# Shows a student's view of problem and submission
sub jscriptNform {
- my ($url,$symb) = @_;
+ my ($symb) = @_;
my $jscript=''."\n";
$jscript.= '
'."\n".
''."\n";
+ 'value="Next->" />'."\n";
if ($ctr == 0) {
my $num_students=(scalar(keys(%$fullname)));
if ($num_students eq 0) {
- $gradeTable=' There are no students currently enrolled.';
+ $gradeTable=' There are no students currently enrolled.';
} else {
- $gradeTable=' '.
- 'No submissions found for this resource for any students. ('.$num_students.
- ' checked for submissions ';
+ my $submissions='submissions';
+ if ($submitonly eq 'incorrect') { $submissions = 'incorrect submissions'; }
+ if ($submitonly eq 'graded' ) { $submissions = 'ungraded submissions'; }
+ if ($submitonly eq 'queued' ) { $submissions = 'queued submissions'; }
+ $gradeTable=' '.
+ 'No '.$submissions.' found for this resource for any students. ('.$num_students.
+ ' students checked for '.$submissions.') ';
}
} elsif ($ctr == 1) {
$gradeTable =~ s/type=checkbox/type=checkbox checked/;
}
- $gradeTable.=&show_grading_menu_form($symb,$url);
+ $gradeTable.=&show_grading_menu_form($symb);
$request->print($gradeTable);
return '';
}
#---- Called from the listStudents routine
+
+sub check_script {
+ my ($form, $type)=@_;
+ my $chkallscript=''."\n";
+ return $chkallscript;
+}
+
+sub check_buttons {
+ my $buttons.='';
+ $buttons.=' ';
+ $buttons.='';
+ $buttons.=' ';
+ return $buttons;
+}
+
# Displays the submissions for one student or a group of students
sub processGroup {
my ($request) = shift;
my $ctr = 0;
- my @stuchecked = (ref($ENV{'form.stuinfo'}) ? @{$ENV{'form.stuinfo'}}
- : ($ENV{'form.stuinfo'}));
+ my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');
my $total = scalar(@stuchecked)-1;
- foreach (@stuchecked) {
- my ($uname,$udom,$fullname) = split(/:/);
- $ENV{'form.student'} = $uname;
- $ENV{'form.userdom'} = $udom;
- $ENV{'form.fullname'} = $fullname;
+ foreach my $student (@stuchecked) {
+ my ($uname,$udom,$fullname) = split(/:/,$student);
+ $env{'form.student'} = $uname;
+ $env{'form.userdom'} = $udom;
+ $env{'form.fullname'} = $fullname;
&submission($request,$ctr,$total);
$ctr++;
}
@@ -625,9 +993,9 @@ sub sub_page_js {
$request->print(<
function updateRadio(formname,id,weight) {
- var gradeBox = eval("formname.GD_BOX"+id);
- var radioButton = eval("formname.RADVAL"+id);
- var oldpts = eval("formname.oldpts"+id+".value");
+ var gradeBox = formname["GD_BOX"+id];
+ var radioButton = formname["RADVAL"+id];
+ var oldpts = formname["oldpts"+id].value;
var pts = checkSolved(formname,id) == 'update' ? gradeBox.value : oldpts;
gradeBox.value = pts;
var resetbox = false;
@@ -649,7 +1017,7 @@ sub sub_page_js {
var resp = confirm("You entered a value ("+pts+
") greater than the weight for the part. Accept?");
if (resp == false) {
- gradeBox.value = "";
+ gradeBox.value = oldpts;
return;
}
}
@@ -661,18 +1029,17 @@ sub sub_page_js {
}
}
updateSelect(formname,id);
- var stores = eval("formname.stores"+id);
- stores.value = "0";
+ formname["stores"+id].value = "0";
}
function writeBox(formname,id,pts) {
- var gradeBox = eval("formname.GD_BOX"+id);
+ var gradeBox = formname["GD_BOX"+id];
if (checkSolved(formname,id) == 'update') {
gradeBox.value = pts;
} else {
- var oldpts = eval("formname.oldpts"+id+".value");
+ var oldpts = formname["oldpts"+id].value;
gradeBox.value = oldpts;
- var radioButton = eval("formname.RADVAL"+id);
+ var radioButton = formname["RADVAL"+id];
for (var i=0; idir_config('lonIconsURL');
&commonJSfunctions($request);
+
+ my $inner_js_msg_central=<
+ function checkInput() {
+ opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);
+ var nmsg = opener.document.SCORE.savemsgN.value;
+ var usrctr = document.msgcenter.usrctr.value;
+ var newval = opener.document.SCORE["newmsg"+usrctr];
+ newval.value = opener.checkEntities(document.msgcenter.newmsg.value);
+
+ var msgchk = "";
+ if (document.msgcenter.subchk.checked) {
+ msgchk = "msgsub,";
+ }
+ var includemsg = 0;
+ for (var i=1; i<=nmsg; i++) {
+ var opnmsg = opener.document.SCORE["savemsg"+i];
+ var frmmsg = document.msgcenter["msg"+i];
+ opnmsg.value = opener.checkEntities(frmmsg.value);
+ var showflg = opener.document.SCORE["shownOnce"+i];
+ showflg.value = "1";
+ var chkbox = document.msgcenter["msgn"+i];
+ if (chkbox.checked) {
+ msgchk += "savemsg"+i+",";
+ includemsg = 1;
+ }
+ }
+ if (document.msgcenter.newmsgchk.checked) {
+ msgchk += "newmsg"+usrctr;
+ includemsg = 1;
+ }
+ imgformname = opener.document.SCORE["mailicon"+usrctr];
+ imgformname.src = "$iconpath/"+((includemsg) ? "mailto.gif" : "mailbkgrd.gif");
+ var includemsg = opener.document.SCORE["includemsg"+usrctr];
+ includemsg.value = msgchk;
+
+ self.close()
+
+ }
+
+INNERJS
+
+ my $inner_js_highlight_central=<
+ function updateChoice(flag) {
+ opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);
+ opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);
+ opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle);
+ opener.document.SCORE.refresh.value = "on";
+ if (opener.document.SCORE.keywords.value!=""){
+ opener.document.SCORE.submit();
+ }
+ self.close()
+ }
+
+INNERJS
+
+ my $start_page_msg_central =
+ &Apache::loncommon::start_page('Message Central',$inner_js_msg_central,
+ {'js_ready' => 1,
+ 'only_body' => 1,
+ 'bgcolor' =>'#FFFFFF',});
+ my $end_page_msg_central =
+ &Apache::loncommon::end_page({'js_ready' => 1});
+
+
+ my $start_page_highlight_central =
+ &Apache::loncommon::start_page('Highlight Central',
+ $inner_js_highlight_central,
+ {'js_ready' => 1,
+ 'only_body' => 1,
+ 'bgcolor' =>'#FFFFFF',});
+ my $end_page_highlight_central =
+ &Apache::loncommon::end_page({'js_ready' => 1});
+
+ my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
+ $docopen=~s/^document\.//;
$request->print(<
//===================== Show list of keywords ====================
- function keywords(keyform) {
- var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",keyform.value);
+ function keywords(formname) {
+ var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",formname.keywords.value);
if (nret==null) return;
- keyform.value = nret;
+ formname.keywords.value = nret;
- document.SCORE.refresh.value = "on";
- if (document.SCORE.keywords.value != "") {
- document.SCORE.submit();
+ if (formname.keywords.value != "") {
+ formname.refresh.value = "on";
+ formname.submit();
}
return;
}
@@ -832,10 +1282,9 @@ sub sub_page_kw_js {
}
var nret = prompt("Add selection to keyword list? Edit if desired.",cleantxt);
if (nret==null) return;
- var curlist = document.SCORE.keywords.value;
- document.SCORE.keywords.value = curlist+" "+nret;
- document.SCORE.refresh.value = "on";
+ document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret;
if (document.SCORE.keywords.value != "") {
+ document.SCORE.refresh.value = "on";
document.SCORE.submit();
}
return;
@@ -852,21 +1301,23 @@ sub sub_page_kw_js {
var Nmsg = msgform.savemsgN.value;
savedMsgHeader(Nmsg,usrctr,fullname);
var subject = msgform.msgsub.value;
- var rtrchk = eval("document.SCORE.includemsg"+usrctr);
- var msgchk = rtrchk.value;
+ var msgchk = document.SCORE["includemsg"+usrctr].value;
re = /msgsub/;
var shwsel = "";
if (re.test(msgchk)) { shwsel = "checked" }
- displaySubject(subject,shwsel);
+ subject = (document.SCORE.shownSub.value == 0 ? checkEntities(subject) : subject);
+ displaySubject(checkEntities(subject),shwsel);
for (var i=1; i<=Nmsg; i++) {
- var testpt = "savemsg"+i+",";
- re = /testpt/;
+ var testmsg = "savemsg"+i+",";
+ re = new RegExp(testmsg,"g");
shwsel = "";
if (re.test(msgchk)) { shwsel = "checked" }
- var message = eval("document.SCORE.savemsg"+i+".value");
- displaySavedMsg(i,message,shwsel);
+ var message = document.SCORE["savemsg"+i].value;
+ message = (document.SCORE["shownOnce"+i].value == 0 ? checkEntities(message) : message);
+ displaySavedMsg(i,message,shwsel); //I do not get it. w/o checkEntities on saved messages,
+ //any < is already converted to <, etc. However, only once!!
}
- newmsg = eval("document.SCORE.newmsg"+usrctr+".value");
+ newmsg = document.SCORE["newmsg"+usrctr].value;
shwsel = "";
re = /newmsg/;
if (re.test(msgchk)) { shwsel = "checked" }
@@ -875,6 +1326,22 @@ sub sub_page_kw_js {
return;
}
+ function checkEntities(strx) {
+ if (strx.length == 0) return strx;
+ var orgStr = ["&", "<", ">", '"'];
+ var newStr = ["&", "<", ">", """];
+ var counter = 0;
+ while (counter < 4) {
+ strx = strReplace(strx,orgStr[counter],newStr[counter]);
+ counter++;
+ }
+ return strx;
+ }
+
+ function strReplace(strx, orgStr, newStr) {
+ return strx.split(orgStr).join(newStr);
+ }
+
function savedMsgHeader(Nmsg,usrctr,fullname) {
var height = 70*Nmsg+250;
var scrollbar = "no";
@@ -882,62 +1349,20 @@ sub sub_page_kw_js {
height = 600;
scrollbar = "yes";
}
-// if (window.pWin) {window.pWin.close(); window.pWin=null}
var xpos = (screen.width-600)/2;
xpos = (xpos < 0) ? '0' : xpos;
var ypos = (screen.height-height)/2-30;
ypos = (ypos < 0) ? '0' : ypos;
- pWin = window.open('', 'MessageCenter', 'toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=600,height='+height);
+ pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=600,height='+height);
pWin.focus();
pDoc = pWin.document;
- pDoc.write("");
- pDoc.write("Message Central");
-
- pDoc.write("
SUBJAVASCRIPT
}
+sub get_increment {
+ my $increment = $env{'form.increment'};
+ if ($increment != 1 && $increment != .5 && $increment != .25 &&
+ $increment != .1) {
+ $increment = 1;
+ }
+ return $increment;
+}
+
#--- displays the grading box, used in essay type problem and grading by page/sequence
sub gradeBox {
my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_;
-
- my $checkIcon = '';
-
my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
my $wgtmsg = ($wgt > 0 ? '(problem weight)' :
- 'problem weight assigned by computer');
+ 'problem weight assigned by computer');
$wgt = ($wgt > 0 ? $wgt : '1');
my $score = ($$record{'resource.'.$partid.'.awarded'} eq '' ?
- '' : $$record{'resource.'.$partid.'.awarded'}*$wgt);
+ '' : &compute_points($$record{'resource.'.$partid.'.awarded'},$wgt));
my $result=''."\n";
-
+ my $display_part=&get_display_part($partid,$symb);
+ my %last_resets = &get_last_resets($symb,$env{'request.course.id'},
+ [$partid]);
+ my $aggtries = $$record{'resource.'.$partid.'.tries'};
+ if ($last_resets{$partid}) {
+ $aggtries = &get_num_tries($record,$last_resets{$partid},$partid);
+ }
$result.='
'.
- 'Part '.$partid.' Points:
'."\n";
-
+ 'Part: '.$display_part.' Points:
'."\n";
my $ctr = 0;
+ my $thisweight = 0;
+ my $increment = &get_increment();
$result.='
'."\n"; # display radio buttons in a nice table 10 across
- while ($ctr<=$wgt) {
- $result.= '
'.$$string[0];
+ } else {
+ my %seenparts;
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part (@part_response_id) {
+ next if ($env{'form.lastSub'} eq 'hdgrade'
+ && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes');
+
+ my ($partid,$respid) = @{ $part };
+ my $display_part=&get_display_part($partid,$symb);
+ if ($env{"form.$uname:$udom:$partid:submitted_by"}) {
+ if (exists($seenparts{$partid})) { next; }
+ $seenparts{$partid}=1;
+ my $submitby='Part: '.$display_part.
+ ' Collaborative submission by: '.
+ ''.
+ $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.' ';
+ $request->print($submitby);
+ next;
+ }
+ my $responsetype = $responseType->{$partid}->{$respid};
+ if (!exists($record{"resource.$partid.$respid.submission"})) {
+ $lastsubonly.='
Part: '.
+ $display_part.' ( ID '.$respid.
+ ' ) '.
+ 'Nothing submitted - no attempts
';
+ next;
+ }
+ foreach (@$string) {
+ my ($partid,$respid) = /^resource\.([^\.]*)\.([^\.]*)\.submission/;
+ if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
+ my ($ressub,$subval) = split(/:/,$_,2);
+ # Similarity check
+ my $similar='';
+ if($env{'form.checkPlag'}){
+ my ($oname,$odom,$ocrsid,$oessay,$osim)=
+ &most_similar($uname,$udom,$subval,\%old_essays);
+ if ($osim) {
+ $osim=int($osim*100.0);
+ my %old_course_desc =
+ &Apache::lonnet::coursedescription($ocrsid,
+ {'one_time' => 1});
+
+ $similar="
".
+ &mt('Essay is [_1]% similar to an essay by [_2] ([_3]:[_4]) in course [_5] (course id [_6]:[_7])',
+ $osim,
+ &Apache::loncommon::plainname($oname,$odom),
+ $oname,$odom,
+ $old_course_desc{'description'},
+ $old_course_desc{'num'},
+ $old_course_desc{'domain'}).
+ '
'.
+ &keywords_highlight($oessay).
+ '
';
+ }
+ }
+ my $order=&get_order($partid,$respid,$symb,$uname,$udom);
+ if ($env{'form.lastSub'} eq 'lastonly' ||
+ ($env{'form.lastSub'} eq 'hdgrade' &&
+ $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {
+ my $display_part=&get_display_part($partid,$symb);
+ $lastsubonly.='
Part: '.
+ $display_part.' ( ID '.$respid.
+ ' ) ';
+ my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
+ if (@$files) {
+ $lastsubonly.=' Like all files provided by users, this file may contain virusses ';
+ my $file_counter = 0;
+ foreach my $file (@$files) {
+ $file_counter ++;
+ &Apache::lonnet::allowuploaded('/adm/grades',$file);
+ $lastsubonly.=' '.$file.'';
}
+ $lastsubonly.=' ';
}
+ $lastsubonly.='Submitted Answer: '.
+ &cleanRecord($subval,$responsetype,$symb,$partid,
+ $respid,\%record,$order);
+ if ($similar) {$lastsubonly.="
'."\n");
}
- # essay grading options
- if ($ENV{'form.handgrade'} eq 'yes') {
- $result=''."\n".
- ''."\n".
- ''."\n";
- my ($lastname,$givenn) = split(/,/,$ENV{'form.fullname'});
+ # essay grading message center
+ if ($env{'form.handgrade'} eq 'yes') {
+ my ($lastname,$givenn) = split(/,/,$env{'form.fullname'});
my $msgfor = $givenn.' '.$lastname;
if (scalar(@col_fullnames) > 0) {
my $lastone = pop @col_fullnames;
$msgfor .= ', '.(join ', ',@col_fullnames).' and '.$lastone.'.';
}
$msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript
-# $result.='
'."\n".
+ $result=''."\n".
+ ''."\n";
$result.=' '.
- 'Compose Message to student'.(scalar(@col_fullnames) >= 1 ? 's' : '').' '.
+ ',\''.$msgfor.'\');" target="_self">'.
+ &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').')'.
''."\n".
- ' (Message will be sent when you click on Save & Next below.)'."\n"
- if ($ENV{'form.handgrade'} eq 'yes');
+ ' ('.
+ &mt('Message will be sent when you click on Save & Next below.').")\n";
$request->print($result);
}
+ if ($perm{'vgr'}) {
+ $request->print(' '.
+ &Apache::loncommon::track_student_link(&mt('View recent activity'),
+ $uname,$udom,'check'));
+ }
+ if ($perm{'opa'}) {
+ $request->print(' '.
+ &Apache::loncommon::pprmlink(&mt('Set/Change parameters'),
+ $uname,$udom,$symb,'check'));
+ }
my %seen = ();
my @partlist;
- for (sort keys(%$handgrade)) {
- my ($partid,$respid) = split(/_/);
+ my @gradePartRespid;
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part_response_id (@part_response_id) {
+ my ($partid,$respid) = @{ $part_response_id };
+ my $part_resp = join('_',@{ $part_response_id });
next if ($seen{$partid} > 0);
$seen{$partid}++;
- next if ($$handgrade{$_} =~ /:no$/ && $ENV{'form.lastSub'} =~ /^(hdgrade)$/);
+ next if ($$handgrade{$part_resp} ne 'yes'
+ && $env{'form.lastSub'} eq 'hdgrade');
push @partlist,$partid;
-
+ push @gradePartRespid,$partid.'.'.$respid;
$request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
}
$result=''."\n";
+ $result.=''."\n" if ($counter == 0);
my $ctr = 0;
while ($ctr < scalar(@partlist)) {
$result.='
'.
- ''."\n";
-# if ($ENV{'form.handgrade'} eq 'yes') {
- $endform.=' '."\n";
- my $ntstu =''."\n";
- my $nsel = ($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1');
- $ntstu =~ s/