version 1.408, 2007/06/15 22:12:49
|
version 1.414, 2007/06/16 20:24:25
|
Line 6144 sub gather_clicker_ids {
|
Line 6144 sub gather_clicker_ids {
|
my $clickers = |
my $clickers = |
(&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1]; |
(&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1]; |
foreach my $id (split(/\,/,$clickers)) { |
foreach my $id (split(/\,/,$clickers)) { |
$id=~s/^0+//; |
$id=~s/^[\#0]+//; |
if (exists($clicker_ids{$id})) { |
if (exists($clicker_ids{$id})) { |
$clicker_ids{$id}.=','.$username.':'.$domain; |
$clicker_ids{$id}.=','.$username.':'.$domain; |
} else { |
} else { |
Line 6160 sub gather_adv_clicker_ids {
|
Line 6160 sub gather_adv_clicker_ids {
|
my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum); |
my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum); |
foreach my $element (sort keys %coursepersonnel) { |
foreach my $element (sort(keys(%coursepersonnel))) { |
foreach my $person (split(/\,/,$coursepersonnel{$element})) { |
foreach my $person (split(/\,/,$coursepersonnel{$element})) { |
my ($puname,$pudom)=split(/\:/,$person); |
my ($puname,$pudom)=split(/\:/,$person); |
my $clickers = |
my $clickers = |
(&Apache::lonnet::userenvironment($pudom,$puname,'clickers'))[1]; |
(&Apache::lonnet::userenvironment($pudom,$puname,'clickers'))[1]; |
foreach my $id (split(/\,/,$clickers)) { |
foreach my $id (split(/\,/,$clickers)) { |
$id=~s/^0+//; |
$id=~s/^[\#0]+//; |
if (exists($clicker_ids{$id})) { |
if (exists($clicker_ids{$id})) { |
$clicker_ids{$id}.=','.$puname.':'.$pudom; |
$clicker_ids{$id}.=','.$puname.':'.$pudom; |
} else { |
} else { |
Line 6178 sub gather_adv_clicker_ids {
|
Line 6178 sub gather_adv_clicker_ids {
|
return %clicker_ids; |
return %clicker_ids; |
} |
} |
|
|
|
sub clicker_grading_parameters { |
|
return ('gradingmechanism' => 'scalar', |
|
'upfiletype' => 'scalar', |
|
'specificid' => 'scalar', |
|
'pcorrect' => 'scalar', |
|
'pincorrect' => 'scalar'); |
|
} |
|
|
sub process_clicker { |
sub process_clicker { |
my ($r)=@_; |
my ($r)=@_; |
my ($symb)=&get_symb($r); |
my ($symb)=&get_symb($r); |
Line 6191 sub process_clicker {
|
Line 6199 sub process_clicker {
|
$result.=' <b>'.&mt('Specify a file containing the clicker information for this resource'). |
$result.=' <b>'.&mt('Specify a file containing the clicker information for this resource'). |
'.</b></td></tr>'."\n"; |
'.</b></td></tr>'."\n"; |
$result.='<tr bgcolor=#ffffe6><td>'."\n"; |
$result.='<tr bgcolor=#ffffe6><td>'."\n"; |
|
# Attempt to restore parameters from last session, set defaults if not present |
|
my %Saveable_Parameters=&clicker_grading_parameters(); |
|
&Apache::loncommon::restore_course_settings('grades_clicker', |
|
\%Saveable_Parameters); |
|
if (!$env{'form.pcorrect'}) { $env{'form.pcorrect'}=100; } |
|
if (!$env{'form.pincorrect'}) { $env{'form.pincorrect'}=100; } |
|
if (!$env{'form.gradingmechanism'}) { $env{'form.gradingmechanism'}='attendance'; } |
|
if (!$env{'form.upfiletype'}) { $env{'form.upfiletype'}='iclicker'; } |
|
|
|
my %checked; |
|
foreach my $gradingmechanism ('attendance','personnel','specific') { |
|
if ($env{'form.gradingmechanism'} eq $gradingmechanism) { |
|
$checked{$gradingmechanism}="checked='checked'"; |
|
} |
|
} |
|
|
my $upload=&mt("Upload File"); |
my $upload=&mt("Upload File"); |
my $type=&mt("Type"); |
my $type=&mt("Type"); |
my $attendance=&mt("Award points just for participation"); |
my $attendance=&mt("Award points just for participation"); |
my $personnel=&mt("Correctness determined from response by course personnel"); |
my $personnel=&mt("Correctness determined from response by course personnel"); |
my $specific=&mt("Correctness determined from response with clicker ID"); |
my $specific=&mt("Correctness determined from response with clicker ID(s)"); |
my $pcorrect=&mt("Percentage points for correct solution"); |
my $pcorrect=&mt("Percentage points for correct solution"); |
my $pincorrect=&mt("Percentage points for incorrect solution"); |
my $pincorrect=&mt("Percentage points for incorrect solution"); |
my $selectform=&Apache::loncommon::select_form('iclicker','upfiletype', |
my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype', |
('iclicker' => 'i>clicker')); |
('iclicker' => 'i>clicker')); |
|
|
$result.=<<ENDUPFORM; |
$result.=<<ENDUPFORM; |
Line 6248 function sanitycheck() {
|
Line 6272 function sanitycheck() {
|
<input type="hidden" name="saveState" value="$env{'form.saveState'}" /> |
<input type="hidden" name="saveState" value="$env{'form.saveState'}" /> |
<input type="file" name="upfile" size="50" /> |
<input type="file" name="upfile" size="50" /> |
<br /><label>$type: $selectform</label> |
<br /><label>$type: $selectform</label> |
<br /><label>$attendance: <input type="radio" name="gradingmechanism" value="attendance" checked="checked" onClick="sanitycheck()" /></label> |
<br /><label>$attendance: <input type="radio" name="gradingmechanism" value="attendance" $checked{'attendance'} onClick="sanitycheck()" /></label> |
<br /><label>$personnel: <input type="radio" name="gradingmechanism" value="personnel" onClick="sanitycheck()" /></label> |
<br /><label>$personnel: <input type="radio" name="gradingmechanism" value="personnel" $checked{'personnel'} onClick="sanitycheck()" /></label> |
<br /><label>$specific: <input type="radio" name="gradingmechanism" value="specific" onClick="sanitycheck()" /></label> |
<br /><label>$specific: <input type="radio" name="gradingmechanism" value="specific" $checked{'specific'} onClick="sanitycheck()" /></label> |
<input type="text" name="specificid" size="15" /> |
<input type="text" name="specificid" value="$env{'form.specificid'}" size="20" /> |
<input type="hidden" name="waschecked" value="attendance" /> |
<input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" /> |
<br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="100" onChange="sanitycheck()" /></label> |
<br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onChange="sanitycheck()" /></label> |
<br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="100" onChange="sanitycheck()" /></label> |
<br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onChange="sanitycheck()" /></label> |
<br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" /> |
<br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" /> |
</form> |
</form> |
ENDUPFORM |
ENDUPFORM |
Line 6268 sub process_clicker_file {
|
Line 6292 sub process_clicker_file {
|
my ($r)=@_; |
my ($r)=@_; |
my ($symb)=&get_symb($r); |
my ($symb)=&get_symb($r); |
if (!$symb) {return '';} |
if (!$symb) {return '';} |
|
|
|
my %Saveable_Parameters=&clicker_grading_parameters(); |
|
&Apache::loncommon::store_course_settings('grades_clicker', |
|
\%Saveable_Parameters); |
|
|
my ($result) = &showResourceInfo($symb,$env{'form.probTitle'}); |
my ($result) = &showResourceInfo($symb,$env{'form.probTitle'}); |
if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) { |
if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) { |
$result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>'; |
$result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>'; |
Line 6279 sub process_clicker_file {
|
Line 6308 sub process_clicker_file {
|
%correct_ids=&gather_adv_clicker_ids(); |
%correct_ids=&gather_adv_clicker_ids(); |
} |
} |
if ($env{'form.gradingmechanism'} eq 'specific') { |
if ($env{'form.gradingmechanism'} eq 'specific') { |
my $correct_id=$env{'form.specificid'}; |
foreach my $correct_id (split(/[\s\,]/,$env{'form.specificid'})) {; |
$correct_id=~tr/a-z/A-Z/; |
$correct_id=~tr/a-z/A-Z/; |
$correct_id=~s/\s//gs; |
$correct_id=~s/\s//gs; |
$correct_id=~s/^0+//; |
$correct_id=~s/^[\#0]+//; |
$correct_ids{$correct_id}='specified'; |
if ($correct_id) { |
|
$correct_ids{$correct_id}='specified'; |
|
} |
|
} |
} |
} |
if ($env{'form.gradingmechanism'} eq 'attendance') { |
if ($env{'form.gradingmechanism'} eq 'attendance') { |
$result.=&mt('Score based on attendance only'); |
$result.=&mt('Score based on attendance only'); |
} else { |
} else { |
my $number=0; |
my $number=0; |
$result.='<h3>'.&mt('Correctness determined by the following IDs').'</h3>'; |
$result.='<p><b>'.&mt('Correctness determined by the following IDs').'</b>'; |
foreach my $id (sort(keys(%correct_ids))) { |
foreach my $id (sort(keys(%correct_ids))) { |
$result.='<tt>'.$id.'</tt> - '; |
$result.='<br /><tt>'.$id.'</tt> - '; |
if ($correct_ids{$id} eq 'specified') { |
if ($correct_ids{$id} eq 'specified') { |
$result.=&mt('specified'); |
$result.=&mt('specified'); |
} else { |
} else { |
my ($uname,$udom)=split(/\:/,$correct_ids{$id}); |
my ($uname,$udom)=split(/\:/,$correct_ids{$id}); |
$result.=&Apache::loncommon::plainname($uname,$udom); |
$result.=&Apache::loncommon::plainname($uname,$udom); |
} |
} |
$result.='<br />'; |
|
$number++; |
$number++; |
} |
} |
|
$result.="</p>\n"; |
if ($number==0) { |
if ($number==0) { |
$result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>'; |
$result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>'; |
return $result.&show_grading_menu_form($symb); |
return $result.&show_grading_menu_form($symb); |
Line 6313 sub process_clicker_file {
|
Line 6345 sub process_clicker_file {
|
'<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'); |
'<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'); |
return $result.&show_grading_menu_form($symb); |
return $result.&show_grading_menu_form($symb); |
} |
} |
|
|
|
# Were able to get all the info needed, now analyze the file |
|
|
|
$result.=&Apache::loncommon::studentbrowser_javascript(); |
|
my $heading=&mt('Scanning clicker file'); |
|
$result.=(<<ENDHEADER); |
|
<br /><table width="100%" border="0"><tr><td bgcolor="#777777"> |
|
<table width="100%" border="0"><tr bgcolor="#e6ffff"><td> |
|
<b>$heading</b></td></tr><tr bgcolor=#ffffe6><td> |
|
<form method="post" action="/adm/grades" name="clickeranalysis"> |
|
<input type="hidden" name="symb" value="$symb" /> |
|
<input type="hidden" name="command" value="assignclickergrades" /> |
|
<input type="hidden" name="probTitle" value="$env{'form.probTitle'}" /> |
|
<input type="hidden" name="saveState" value="$env{'form.saveState'}" /> |
|
<input type="hidden" name="gradingmechanism" value="$env{'form.gradingmechanism'}" /> |
|
<input type="hidden" name="pcorrect" value="$env{'form.pcorrect'}" /> |
|
<input type="hidden" name="pincorrect" value="$env{'form.pincorrect'}" /> |
|
ENDHEADER |
my %responses; |
my %responses; |
my @questiontitles; |
my @questiontitles; |
my $errormsg=''; |
my $errormsg=''; |
Line 6320 sub process_clicker_file {
|
Line 6370 sub process_clicker_file {
|
if ($env{'form.upfiletype'} eq 'iclicker') { |
if ($env{'form.upfiletype'} eq 'iclicker') { |
($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses); |
($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses); |
} |
} |
$result.='<br />'.&mt('Found [_1] questions',$number).'<br />'; |
$result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />'. |
foreach my $id (keys %responses) { |
'<input type="hidden" name="number" value="'.$number.'" />'. |
$result.='<br />'.$id.' - '.$responses{$id}; |
&mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses', |
|
$env{'form.pcorrect'},$env{'form.pincorrect'}). |
|
'<br />'; |
|
# Remember Question Titles |
|
# FIXME: Possibly need delimiter other than ":" |
|
for (my $i=0;$i<$number;$i++) { |
|
$result.='<input type="hidden" name="question:'.$i.'" value="'. |
|
&HTML::Entities::encode($questiontitles[$i],'"&<>').'" />'; |
|
} |
|
my $correct_count=0; |
|
my $student_count=0; |
|
my $unknown_count=0; |
|
# Match answers with usernames |
|
# FIXME: Possibly need delimiter other than ":" |
|
foreach my $id (keys(%responses)) { |
|
if ($correct_ids{$id}) { |
|
$result.="\n".'<input type="hidden" name="correct:'.$correct_count.':'.$correct_ids{$id}.'" value="'.$responses{$id}.'" />'; |
|
$correct_count++; |
|
} elsif ($clicker_ids{$id}) { |
|
$result.="\n".'<input type="hidden" name="student:'.$clicker_ids{$id}.'" value="'.$responses{$id}.'" />'; |
|
$student_count++; |
|
} else { |
|
$result.="\n<hr />".&mt('Unregistered Clicker')." <tt>".$id."</tt><br />"; |
|
$result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'. |
|
"\n".&mt("Username").": <input type='text' name='uname".$id."' /> ". |
|
"\n".&mt("Domain").": ". |
|
&Apache::loncommon::select_dom_form($env{'course.'.$env{'request.course.id'}.'.domain'},'udom'.$id).' '. |
|
&Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id); |
|
$unknown_count++; |
|
} |
|
} |
|
$result.='<hr />'. |
|
&mt('Found [_1] registered and [_2] unregistered clickers.',$student_count,$unknown_count); |
|
if ($env{'form.gradingmechanism'} ne 'attendance') { |
|
if ($correct_count==0) { |
|
$errormsg.="Found no correct answers answers for grading!"; |
|
} elsif ($correct_count>1) { |
|
$result.='<br /><span class="LC_warning">'.&mt("Found [_1] entries for grading!",$correct_count).'</span>'; |
|
} |
} |
} |
|
if ($errormsg) { |
|
$result.='<br /><span class="LC_error">'.&mt($errormsg).'</span>'; |
|
} else { |
|
$result.='<br /><input type="submit" name="finalize" value="'.&mt('Finalize Grading').'" />'; |
|
} |
|
$result.='</form></td></tr></table>'."\n". |
|
'</td></tr></table><br /><br />'."\n"; |
return $result.&show_grading_menu_form($symb); |
return $result.&show_grading_menu_form($symb); |
} |
} |
|
|
Line 6332 sub iclicker_eval {
|
Line 6427 sub iclicker_eval {
|
my $number=0; |
my $number=0; |
my $errormsg=''; |
my $errormsg=''; |
foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) { |
foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) { |
chomp($line); |
my %components=&Apache::loncommon::record_sep($line); |
foreach my $quoted ($line=~/\,\s*\"([^\"]*)\"\s*\,/g) { |
my @entries=map {$components{$_}} (sort(keys(%components))); |
my $replace=$quoted; |
|
$replace=~s/\,//g; |
|
&Apache::lonnet::logthis($quoted.' - '.$replace.'<br />'); |
|
$line=~s/\,\s*\"\Q$quoted\E\"\s*\,/,$replace,/gs; |
|
} |
|
my @entries=split(/\,/,$line); |
|
if ($entries[0] eq 'Question') { |
if ($entries[0] eq 'Question') { |
for (my $i=3;$i<$#entries;$i+=6) { |
for (my $i=3;$i<$#entries;$i+=6) { |
$$questiontitles[$number]=$entries[$i]; |
$$questiontitles[$number]=$entries[$i]; |
Line 6360 sub iclicker_eval {
|
Line 6449 sub iclicker_eval {
|
return ($errormsg,$number); |
return ($errormsg,$number); |
} |
} |
|
|
|
sub assign_clicker_grades { |
|
my ($r)=@_; |
|
my ($symb)=&get_symb($r); |
|
if (!$symb) {return '';} |
|
my ($result) = &showResourceInfo($symb,$env{'form.probTitle'}); |
|
my $heading=&mt('Assigning grades based on clicker file'); |
|
$result.=(<<ENDHEADER); |
|
<br /><table width="100%" border="0"><tr><td bgcolor="#777777"> |
|
<table width="100%" border="0"><tr bgcolor="#e6ffff"><td> |
|
<b>$heading</b></td></tr><tr bgcolor=#ffffe6><td> |
|
ENDHEADER |
|
# Get correct result |
|
# FIXME: Possibly need delimiter other than ":" |
|
my @correct=(); |
|
if ($env{'form.gradingmechanism'} ne 'attendance') { |
|
foreach my $key (keys(%env)) { |
|
if ($key=~/^form\.correct\:/) { |
|
my @input=split(/\,/,$env{$key}); |
|
for (my $i=0;$i<=$#input;$i++) { |
|
if (($correct[$i]) && ($input[$i]) && |
|
($correct[$i] ne $input[$i])) { |
|
$result.='<br /><span class="LC_warning">'. |
|
&mt('More than one correct result given for question "[_1]": [_2] versus [_3].', |
|
$env{'form.question:'.$i},$correct[$i],$input[$i]).'</span>'; |
|
} elsif ($input[$i]) { |
|
$correct[$i]=$input[$i]; |
|
} |
|
} |
|
} |
|
} |
|
for (my $i=0;$i<$env{'form.number'};$i++) { |
|
if (!$correct[$i]) { |
|
$result.='<br /><span class="LC_error">'. |
|
&mt('No correct result given for question "[_1]"!', |
|
$env{'form.question:'.$i}).'</span>'; |
|
} |
|
} |
|
$result.='<br />'.&mt("Correct answer: [_1]",join(', ',map { ($_?$_:'-') } @correct)); |
|
} |
|
# Start grading |
|
$result.='</td></tr></table>'."\n". |
|
'</td></tr></table><br /><br />'."\n"; |
|
return $result.&show_grading_menu_form($symb); |
|
} |
|
|
sub handler { |
sub handler { |
my $request=$_[0]; |
my $request=$_[0]; |
|
|
Line 6431 sub handler {
|
Line 6565 sub handler {
|
$request->print(&process_clicker($request)); |
$request->print(&process_clicker($request)); |
} elsif ($command eq 'processclickerfile' && $perm{'mgr'}) { |
} elsif ($command eq 'processclickerfile' && $perm{'mgr'}) { |
$request->print(&process_clicker_file($request)); |
$request->print(&process_clicker_file($request)); |
|
} elsif ($command eq 'assignclickergrades' && $perm{'mgr'}) { |
|
$request->print(&assign_clicker_grades($request)); |
} elsif ($command eq 'csvform' && $perm{'mgr'}) { |
} elsif ($command eq 'csvform' && $perm{'mgr'}) { |
$request->print(&upcsvScores_form($request)); |
$request->print(&upcsvScores_form($request)); |
} elsif ($command eq 'csvupload' && $perm{'mgr'}) { |
} elsif ($command eq 'csvupload' && $perm{'mgr'}) { |