version 1.528.2.3, 2008/12/22 15:13:45
|
version 1.538, 2008/12/20 04:04:36
|
Line 26
|
Line 26
|
# http://www.lon-capa.org/ |
# http://www.lon-capa.org/ |
# |
# |
|
|
|
|
|
|
package Apache::grades; |
package Apache::grades; |
use strict; |
use strict; |
use Apache::style; |
use Apache::style; |
Line 58 my $ssi_error_resource;
|
Line 60 my $ssi_error_resource;
|
my $ssi_error_message; |
my $ssi_error_message; |
|
|
|
|
# Do an ssi with retries: |
|
# While I'd love to factor out this with the vesrion in lonprintout, |
|
# that would either require a data coupling between modules, which I refuse to perpetuate |
|
# (there's quite enough of that already), or would require the invention of another infrastructure |
|
# I'm not quite ready to invent (e.g. an ssi_with_retry object). |
|
# |
|
# At least the logic that drives this has been pulled out into loncommon. |
|
|
|
|
|
# |
|
# ssi_with_retries - Does the server side include of a resource. |
|
# if the ssi call returns an error we'll retry it up to |
|
# the number of times requested by the caller. |
|
# If we still have a proble, no text is appended to the |
|
# output and we set some global variables. |
|
# to indicate to the caller an SSI error occurred. |
|
# All of this is supposed to deal with the issues described |
|
# in LonCAPA BZ 5631 see: |
|
# http://bugs.lon-capa.org/show_bug.cgi?id=5631 |
|
# by informing the user that this happened. |
|
# |
|
# Parameters: |
|
# resource - The resource to include. This is passed directly, without |
|
# interpretation to lonnet::ssi. |
|
# form - The form hash parameters that guide the interpretation of the resource |
|
# |
|
# retries - Number of retries allowed before giving up completely. |
|
# Returns: |
|
# On success, returns the rendered resource identified by the resource parameter. |
|
# Side Effects: |
|
# The following global variables can be set: |
|
# ssi_error - If an unrecoverable error occurred this becomes true. |
|
# It is up to the caller to initialize this to false |
|
# if desired. |
|
# ssi_error_resource - If an unrecoverable error occurred, this is the value |
|
# of the resource that could not be rendered by the ssi |
|
# call. |
|
# ssi_error_message - The error string fetched from the ssi response |
|
# in the event of an error. |
|
# |
|
sub ssi_with_retries { |
sub ssi_with_retries { |
my ($resource, $retries, %form) = @_; |
my ($resource, $retries, %form) = @_; |
my ($content, $response) = &Apache::loncommon::ssi_with_retries($resource, $retries, %form); |
my ($content, $response) = &Apache::loncommon::ssi_with_retries($resource, $retries, %form); |
Line 3834 sub upcsvScores_form {
|
Line 3796 sub upcsvScores_form {
|
$result.=$table; |
$result.=$table; |
$result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; |
$result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; |
$result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; |
$result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; |
$result.=' <b>'.&mt('Specify a file containing the class scores for current resource'). |
$result.=' <b>'.&mt('Specify a file containing the class scores for current resource.'). |
'.</b></td></tr>'."\n"; |
'</b></td></tr>'."\n"; |
$result.='<tr bgcolor=#ffffe6><td>'."\n"; |
$result.='<tr bgcolor=#ffffe6><td>'."\n"; |
my $upload=&mt("Upload Scores"); |
my $upload=&mt("Upload Scores"); |
my $upfile_select=&Apache::loncommon::upfile_select_html(); |
my $upfile_select=&Apache::loncommon::upfile_select_html(); |
Line 6613 sub scantron_validate_sequence {
|
Line 6575 sub scantron_validate_sequence {
|
return (0,$currentphase+1); |
return (0,$currentphase+1); |
} |
} |
|
|
=pod |
|
|
|
=item scantron_validate_ID |
|
|
|
Validates all scanlines in the selected file to not have any |
|
invalid or underspecified student IDs |
|
|
|
=cut |
|
|
|
sub scantron_validate_ID { |
sub scantron_validate_ID { |
my ($r,$currentphase) = @_; |
my ($r,$currentphase) = @_; |
Line 6686 sub scantron_validate_ID {
|
Line 6641 sub scantron_validate_ID {
|
return (0,$currentphase+1); |
return (0,$currentphase+1); |
} |
} |
|
|
=pod |
|
|
|
=item scantron_get_correction |
|
|
|
Builds the interface screen to interact with the operator to fix a |
|
specific error condition in a specific scanline |
|
|
|
Arguments: |
|
$r - Apache request object |
|
$i - number of the current scanline |
|
$scan_record - hash ref as returned from &scantron_parse_scanline() |
|
$scan_config - hash ref as returned from &get_scantron_config() |
|
$line - full contents of the current scanline |
|
$error - error condition, valid values are |
|
'incorrectCODE', 'duplicateCODE', |
|
'doublebubble', 'missingbubble', |
|
'duplicateID', 'incorrectID' |
|
$arg - extra information needed |
|
For errors: |
|
- duplicateID - paper number that this studentID was seen before on |
|
- duplicateCODE - array ref of the paper numbers this CODE was |
|
seen on before |
|
- incorrectCODE - current incorrect CODE |
|
- doublebubble - array ref of the bubble lines that have double |
|
bubble errors |
|
- missingbubble - array ref of the bubble lines that have missing |
|
bubble errors |
|
|
|
=cut |
|
|
|
sub scantron_get_correction { |
sub scantron_get_correction { |
my ($r,$i,$scan_record,$scan_config,$line,$error,$arg)=@_; |
my ($r,$i,$scan_record,$scan_config,$line,$error,$arg)=@_; |
Line 7285 sub scantron_validate_doublebubble {
|
Line 7211 sub scantron_validate_doublebubble {
|
return (0,$currentphase+1); |
return (0,$currentphase+1); |
} |
} |
|
|
=pod |
|
|
|
=item scantron_get_maxbubble |
|
|
|
Returns the maximum number of bubble lines that are expected to |
|
occur. Does this by walking the selected sequence rendering the |
|
resource and then checking &Apache::lonxml::get_problem_counter() |
|
for what the current value of the problem counter is. |
|
|
|
Caches the results to $env{'form.scantron_maxbubble'}, |
|
$env{'form.scantron.bubble_lines.n'}, |
|
$env{'form.scantron.first_bubble_line.n'} and |
|
$env{"form.scantron.sub_bubblelines.n"} |
|
which are the total number of bubble, lines, the number of bubble |
|
lines for response n and number of the first bubble line for response n, |
|
and a comma separated list of numbers of bubble lines for sub-questions |
|
(for optionresponse, matchresponse, and rankresponse items), for response n. |
|
|
|
=cut |
|
|
|
sub scantron_get_maxbubble { |
sub scantron_get_maxbubble { |
if (defined($env{'form.scantron_maxbubble'}) && |
if (defined($env{'form.scantron_maxbubble'}) && |
Line 7335 sub scantron_get_maxbubble {
|
Line 7242 sub scantron_get_maxbubble {
|
foreach my $resource (@resources) { |
foreach my $resource (@resources) { |
my $symb = $resource->symb(); |
my $symb = $resource->symb(); |
|
|
my @parts; |
my (@parts,@allparts,@possible_parts); |
|
|
|
# Need to retrieve part IDs and response IDs because essayresponse, |
|
# reactionresponse and organicresponse items are not included in |
|
# $analysis{'parts'} from lonnet::ssi. |
|
if (ref($resource->parts()) eq 'ARRAY') { |
|
foreach my $part (@{$resource->parts()}) { |
|
if (!&Apache::loncommon::check_if_partid_hidden($part,$symb,$udom,$uname)) { |
|
my @resp_ids = $resource->responseIds($part); |
|
foreach my $id (@resp_ids) { |
|
my $part_id = $part.'.'.$id; |
|
push(@possible_parts,$part_id); |
|
} |
|
} |
|
} |
|
} |
|
|
my $result=&ssi_with_retries($resource->src(), $ssi_retries, |
my $result=&ssi_with_retries($resource->src(), $ssi_retries, |
('symb' => $symb, |
('symb' => $symb, |
Line 7356 sub scantron_get_maxbubble {
|
Line 7278 sub scantron_get_maxbubble {
|
} |
} |
} |
} |
} |
} |
|
# Add part_ids for any essayresponse, reactionresponse or |
|
# organicresponse items. |
|
foreach my $part_id (@possible_parts) { |
|
if (grep(/^\Q$part_id\E$/,@parts)) { |
|
push(@allparts,$part_id); |
|
} else { |
|
if (($analysis{$part_id.'.type'} eq 'essayresponse') || |
|
($analysis{$part_id.'.type'} eq 'reactionresponse') || |
|
($analysis{$part_id.'.type'} eq 'organicresponse')) { |
|
push(@allparts,$part_id); |
|
} |
|
} |
|
} |
|
|
foreach my $part_id (@parts) { |
foreach my $part_id (@allparts) { |
my $lines; |
my $lines; |
|
|
# TODO - make this a persistent hash not an array. |
# TODO - make this a persistent hash not an array. |
Line 7418 sub scantron_get_maxbubble {
|
Line 7353 sub scantron_get_maxbubble {
|
return $env{'form.scantron_maxbubble'}; |
return $env{'form.scantron_maxbubble'}; |
} |
} |
|
|
=pod |
|
|
|
=item scantron_validate_missingbubbles |
|
|
|
Validates all scanlines in the selected file to not have any |
|
answers that don't have bubbles that have not been verified |
|
to be bubble free. |
|
|
|
=cut |
|
|
|
sub scantron_validate_missingbubbles { |
sub scantron_validate_missingbubbles { |
my ($r,$currentphase) = @_; |
my ($r,$currentphase) = @_; |
Line 7481 sub scantron_validate_missingbubbles {
|
Line 7407 sub scantron_validate_missingbubbles {
|
return (0,$currentphase+1); |
return (0,$currentphase+1); |
} |
} |
|
|
=pod |
|
|
|
=item scantron_process_students |
|
|
|
Routine that does the actual grading of the bubble sheet information. |
|
|
|
The parsed scanline hash is added to %env |
|
|
|
Then foreach unskipped scanline it does an &Apache::lonnet::ssi() |
|
foreach resource , with the form data of |
|
|
|
'submitted' =>'scantron' |
|
'grade_target' =>'grade', |
|
'grade_username'=> username of student |
|
'grade_domain' => domain of student |
|
'grade_courseid'=> of course |
|
'grade_symb' => symb of resource to grade |
|
|
|
This triggers a grading pass. The problem grading code takes care |
|
of converting the bubbled letter information (now in %env) into a |
|
valid submission. |
|
|
|
=cut |
|
|
|
sub scantron_process_students { |
sub scantron_process_students { |
my ($r) = @_; |
my ($r) = @_; |
Line 7634 SCANTRONFORM
|
Line 7537 SCANTRONFORM
|
return ''; |
return ''; |
} |
} |
|
|
=pod |
|
|
|
=item scantron_upload_scantron_data |
|
|
|
Creates the screen for adding a new bubble sheet data file to a course. |
|
|
|
=cut |
|
|
|
sub scantron_upload_scantron_data { |
sub scantron_upload_scantron_data { |
my ($r)=@_; |
my ($r)=@_; |
$r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'})); |
$r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'})); |
Line 7682 sub scantron_upload_scantron_data {
|
Line 7577 sub scantron_upload_scantron_data {
|
return ''; |
return ''; |
} |
} |
|
|
=pod |
|
|
|
=item scantron_upload_scantron_data_save |
|
|
|
Adds a provided bubble information data file to the course if user |
|
has the correct privileges to do so. |
|
|
|
=cut |
|
|
|
sub scantron_upload_scantron_data_save { |
sub scantron_upload_scantron_data_save { |
my($r)=@_; |
my($r)=@_; |
Line 7751 sub scantron_upload_scantron_data_save {
|
Line 7638 sub scantron_upload_scantron_data_save {
|
return ''; |
return ''; |
} |
} |
|
|
=pod |
|
|
|
=item valid_file |
|
|
|
Validates that the requested bubble data file exists in the course. |
|
|
|
=cut |
|
|
|
sub valid_file { |
sub valid_file { |
my ($requested_file)=@_; |
my ($requested_file)=@_; |
foreach my $filename (sort(&scantron_filenames())) { |
foreach my $filename (sort(&scantron_filenames())) { |
Line 7767 sub valid_file {
|
Line 7646 sub valid_file {
|
return 0; |
return 0; |
} |
} |
|
|
=pod |
|
|
|
=item scantron_download_scantron_data |
|
|
|
Shows a list of the three internal files (original, corrected, |
|
skipped) for a specific bubble sheet data file that exists in the |
|
course. |
|
|
|
=cut |
|
|
|
sub scantron_download_scantron_data { |
sub scantron_download_scantron_data { |
my ($r)=@_; |
my ($r)=@_; |
my $default_form_data=&defaultFormData(&get_symb($r,1)); |
my $default_form_data=&defaultFormData(&get_symb($r,1)); |
Line 8081 sub checkscantron_results {
|
Line 7950 sub checkscantron_results {
|
return; |
return; |
} |
} |
|
|
=pod |
|
|
|
=back |
|
|
|
=cut |
|
|
|
#-------- end of section for handling grading scantron forms ------- |
#-------- end of section for handling grading scantron forms ------- |
# |
# |
Line 8132 sub grading_menu {
|
Line 7996 sub grading_menu {
|
'saveState'=>"", |
'saveState'=>"", |
'gradingMenu'=>1, |
'gradingMenu'=>1, |
'showgrading'=>"yes"); |
'showgrading'=>"yes"); |
my $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
|
my @menu = ({ url => $url, |
my $url1 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
name => &mt('Manual Grading/View Submissions'), |
|
short_description => |
|
&mt('Start the process of hand grading submissions.'), |
|
}); |
|
$fields{'command'} = 'csvform'; |
$fields{'command'} = 'csvform'; |
$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
push(@menu, { url => $url, |
|
name => &mt('Upload Scores'), |
|
short_description => |
|
&mt('Specify a file containing the class scores for current resource.')}); |
|
$fields{'command'} = 'processclicker'; |
$fields{'command'} = 'processclicker'; |
$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
my $url3 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
push(@menu, { url => $url, |
|
name => &mt('Process Clicker'), |
|
short_description => |
|
&mt('Specify a file containing the clicker information for this resource.')}); |
|
$fields{'command'} = 'scantron_selectphase'; |
$fields{'command'} = 'scantron_selectphase'; |
$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
my $url4 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
push(@menu, { url => $url, |
|
name => &mt('Grade/Manage/Review Scantron Forms'), |
my @menu = ({ categorytitle=>'Course Grading', |
short_description => |
items =>[ |
&mt('Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.')}); |
{ linktext => 'Manual Grading/View Submissions', |
$fields{'command'} = 'verify'; |
url => $url1, |
$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
permission => 'F', |
push(@menu, { url => "", |
icon => 'edit-find-replace.png', |
name => &mt('Verify Receipt'), |
linktitle => 'Start the process of hand grading submissions.' |
short_description => |
}, |
&mt('')}); |
{ linktext => 'Upload Scores', |
|
url => $url2, |
|
permission => 'F', |
|
icon => 'uploadscores.png', |
|
linktitle => 'Specify a file containing the class scores for current resource.' |
|
}, |
|
{ linktext => 'Process Clicker', |
|
url => $url3, |
|
permission => 'F', |
|
icon => 'addClickerInfoFile.png', |
|
linktitle => 'Specify a file containing the clicker information for this resource.' |
|
}, |
|
{ linktext => 'Grade/Manage/Review Scantron Forms', |
|
url => $url4, |
|
permission => 'F', |
|
icon => 'stat.png', |
|
linktitle => 'Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.' |
|
} |
|
] |
|
}); |
|
|
|
#$fields{'command'} = 'verify'; |
|
#$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); |
# |
# |
# Create the menu |
# Create the menu |
my $Str; |
my $Str; |
Line 8175 sub grading_menu {
|
Line 8052 sub grading_menu {
|
'<input type="hidden" name="gradingMenu" value="1" />'."\n". |
'<input type="hidden" name="gradingMenu" value="1" />'."\n". |
'<input type="hidden" name="showgrading" value="yes" />'."\n"; |
'<input type="hidden" name="showgrading" value="yes" />'."\n"; |
|
|
foreach my $menudata (@menu) { |
$Str .= Apache::lonhtmlcommon::generate_menu(@menu); |
if ($menudata->{'name'} ne &mt('Verify Receipt')) { |
#$menudata->{'jscript'} |
$Str .=' <h3><a '. |
$Str .='<hr /><input type="button" value="'.&mt('Verify Receipt').'" '. |
$menudata->{'jscript'}. |
''. |
' href="'. |
' onClick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '. |
$menudata->{'url'}.'" >'. |
' /> '. |
$menudata->{'name'}."</a></h3>\n"; |
&Apache::lonnet::recprefix($env{'request.course.id'}). |
} else { |
'-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />'; |
$Str .='<hr /><input type="button" value="'.&mt('Verify Receipt').'" '. |
|
$menudata->{'jscript'}. |
|
' onClick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '. |
|
' /> '. |
|
&Apache::lonnet::recprefix($env{'request.course.id'}). |
|
'-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />'; |
|
} |
|
$Str .= ' '.(' 'x8).$menudata->{'short_description'}. |
|
"\n"; |
|
} |
|
$Str .="</form>\n"; |
$Str .="</form>\n"; |
$request->print(<<GRADINGMENUJS); |
$request->print(<<GRADINGMENUJS); |
<script type="text/javascript" language="javascript"> |
<script type="text/javascript" language="javascript"> |
Line 8288 GRADINGMENUJS
|
Line 8156 GRADINGMENUJS
|
my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'}); |
my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'}); |
my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'}); |
my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'}); |
|
|
|
# Preselect sections |
|
my $selsec=""; |
|
if (ref($sections)) { |
|
foreach my $section (sort(@$sections)) { |
|
$selsec.='<option value="'.$section.'" '. |
|
($saveSec eq $section ? 'selected="selected"':'').'>'.$section.'</option>'."\n"; |
|
} |
|
} |
|
|
$result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". |
$result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". |
'<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". |
'<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". |
'<input type="hidden" name="handgrade" value="'.$hdgrade.'" />'."\n". |
'<input type="hidden" name="handgrade" value="'.$hdgrade.'" />'."\n". |
Line 8298 GRADINGMENUJS
|
Line 8175 GRADINGMENUJS
|
'<input type="hidden" name="showgrading" value="yes" />'."\n"; |
'<input type="hidden" name="showgrading" value="yes" />'."\n"; |
|
|
$result.=' |
$result.=' |
<div class="LC_grade_select_mode"> |
<h2> |
<div class="LC_grade_select_mode_current"> |
'.&mt('Grade Current Resource').' |
<h2> |
</h2> |
'.&mt('Grade Current Resource').' |
<div> |
</h2> |
'.$table.' |
<div class="LC_grade_select_mode_body"> |
</div> |
<div class="LC_grades_resource_info"> |
|
'.$table.' |
<div class="LC_columnSection"> |
</div> |
|
<div class="LC_grade_select_mode_selector"> |
<fieldset> |
<div class="LC_grade_select_mode_selector_header"> |
<legend> |
'.&mt('Sections').' |
'.&mt('Sections').' |
</div> |
</legend> |
<div class="LC_grade_select_mode_selector_body"> |
<select name="section" multiple="multiple" size="5">'."\n"; |
<select name="section" multiple="multiple" size="5">'."\n"; |
$result.= $selsec; |
if (ref($sections)) { |
|
foreach my $section (sort(@$sections)) { |
|
$result.='<option value="'.$section.'" '. |
|
($saveSec eq $section ? 'selected="selected"':'').'>'.$section.'</option>'."\n"; |
|
} |
|
} |
|
$result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> '; |
$result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> '; |
$result.=' |
$result.=' |
</div> |
</fieldset> |
</div> |
|
<div class="LC_grade_select_mode_selector"> |
<fieldset> |
<div class="LC_grade_select_mode_selector_header"> |
<legend> |
'.&mt('Groups').' |
'.&mt('Groups').' |
</div> |
</legend> |
<div class="LC_grade_select_mode_selector_body"> |
'.&Apache::lonstatistics::GroupSelect('group','multiple',5).' |
'.&Apache::lonstatistics::GroupSelect('group','multiple',5).' |
</fieldset> |
</div> |
|
</div> |
<fieldset> |
<div class="LC_grade_select_mode_selector"> |
<legend> |
<div class="LC_grade_select_mode_selector_header"> |
'.&mt('Access Status').' |
'.&mt('Access Status').' |
</legend> |
</div> |
'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,5,undef,'mult').' |
<div class="LC_grade_select_mode_selector_body"> |
</fieldset> |
'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,5,undef,'mult').' |
|
</div> |
<fieldset> |
</div> |
<legend> |
<div class="LC_grade_select_mode_selector"> |
'.&mt('Submission Status').' |
<div class="LC_grade_select_mode_selector_header"> |
</legend> |
'.&mt('Submission Status').' |
<select name="submitonly" size="5"> |
</div> |
|
<div class="LC_grade_select_mode_selector_body"> |
|
<select name="submitonly" size="5"> |
|
<option value="yes" '. ($saveSub eq 'yes' ? 'selected="selected"' : '').'>'.&mt('with submissions').'</option> |
<option value="yes" '. ($saveSub eq 'yes' ? 'selected="selected"' : '').'>'.&mt('with submissions').'</option> |
<option value="queued" '. ($saveSub eq 'queued' ? 'selected="selected"' : '').'>'.&mt('in grading queue').'</option> |
<option value="queued" '. ($saveSub eq 'queued' ? 'selected="selected"' : '').'>'.&mt('in grading queue').'</option> |
<option value="graded" '. ($saveSub eq 'graded' ? 'selected="selected"' : '').'>'.&mt('with ungraded submissions').'</option> |
<option value="graded" '. ($saveSub eq 'graded' ? 'selected="selected"' : '').'>'.&mt('with ungraded submissions').'</option> |
<option value="incorrect" '.($saveSub eq 'incorrect' ? 'selected="selected"' : '').'>'.&mt('with incorrect submissions').'</option> |
<option value="incorrect" '.($saveSub eq 'incorrect' ? 'selected="selected"' : '').'>'.&mt('with incorrect submissions').'</option> |
<option value="all" '. ($saveSub eq 'all' ? 'selected="selected"' : '').'>'.&mt('with any status').'</option> |
<option value="all" '. ($saveSub eq 'all' ? 'selected="selected"' : '').'>'.&mt('with any status').'</option> |
</select> |
</select> |
</div> |
</fieldset> |
</div> |
|
<div class="LC_grade_select_mode_type_body"> |
</div> |
<div class="LC_grade_select_mode_type"> |
|
|
<br /> |
|
<div> |
|
<div> |
<label> |
<label> |
<input type="radio" name="radioChoice" value="submission" '. |
<input type="radio" name="radioChoice" value="submission" '. |
($saveCmd eq 'submission' ? 'checked="checked"' : '').' /> '. |
($saveCmd eq 'submission' ? 'checked="checked"' : '').' /> '. |
&mt('Select individual students to grade and view submissions.').' |
&mt('Select individual students to grade and view submissions.').' |
</label> |
</label> |
</div> |
</div> |
<div class="LC_grade_select_mode_type"> |
<div> |
<label> |
<label> |
<input type="radio" name="radioChoice" value="viewgrades" '. |
<input type="radio" name="radioChoice" value="viewgrades" '. |
($saveCmd eq 'viewgrades' ? 'checked="checked"' : '').' /> '. |
($saveCmd eq 'viewgrades' ? 'checked="checked"' : '').' /> '. |
&mt('Grade all selected students in a grading table.').' |
&mt('Grade all selected students in a grading table.').' |
</label> |
</label> |
</div> |
</div> |
<div class="LC_grade_select_mode_type"> |
<div> |
<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next->').'" /> |
<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next->').'" /> |
</div> |
</div> |
</div> |
</div> |
</div> |
|
</div> |
|
<div class="LC_grade_select_mode_page"> |
|
<h2> |
<h2> |
'.&mt('Grade Complete Folder for One Student').' |
'.&mt('Grade Complete Folder for One Student').' |
</h2> |
</h2> |
<div class="LC_grades_select_mode_body"> |
<div> |
<div class="LC_grade_select_mode_type_body"> |
<div> |
<div class="LC_grade_select_mode_type"> |
|
<label> |
<label> |
<input type="radio" name="radioChoice" value="pickStudentPage" '. |
<input type="radio" name="radioChoice" value="pickStudentPage" '. |
($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '. |
($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '. |
&mt('The <b>complete</b> page/sequence/folder: For one student').' |
&mt('The <b>complete</b> page/sequence/folder: For one student').' |
</label> |
</label> |
</div> |
</div> |
<div class="LC_grade_select_mode_type"> |
<div> |
<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next->').'" /> |
<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next->').'" /> |
</div> |
</div> |
</div> |
|
</div> |
</div> |
</div> |
|
</div> |
|
</form>'; |
</form>'; |
$result .= &show_grading_menu_form($symb); |
$result .= &show_grading_menu_form($symb); |
return $result; |
return $result; |
Line 8492 sub process_clicker {
|
Line 8358 sub process_clicker {
|
$result.=$table; |
$result.=$table; |
$result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; |
$result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; |
$result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; |
$result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; |
$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 |
# Attempt to restore parameters from last session, set defaults if not present |
my %Saveable_Parameters=&clicker_grading_parameters(); |
my %Saveable_Parameters=&clicker_grading_parameters(); |
Line 8954 sub handler {
|
Line 8820 sub handler {
|
} |
} |
|
|
$ssi_error = 0; |
$ssi_error = 0; |
$request->print(&Apache::loncommon::start_page('Grading')); |
my $brcrum = [{href=>"/adm/grades",text=>"Grading"}]; |
|
$request->print(&Apache::loncommon::start_page('Grading',undef, |
|
{'bread_crumbs' => $brcrum})); |
if ($symb eq '' && $command eq '') { |
if ($symb eq '' && $command eq '') { |
if ($env{'user.adv'}) { |
if ($env{'user.adv'}) { |
if (($env{'form.codeone'}) && ($env{'form.codetwo'}) && |
if (($env{'form.codeone'}) && ($env{'form.codetwo'}) && |
Line 9066 sub handler {
|
Line 8934 sub handler {
|
1; |
1; |
|
|
__END__; |
__END__; |
|
|
|
|
|
=head1 NAME |
|
|
|
Apache::grades |
|
|
|
=head1 SYNOPSIS |
|
|
|
Handles the viewing of grades. |
|
|
|
This is part of the LearningOnline Network with CAPA project |
|
described at http://www.lon-capa.org. |
|
|
|
=head1 OVERVIEW |
|
|
|
Do an ssi with retries: |
|
While I'd love to factor out this with the vesrion in lonprintout, |
|
that would either require a data coupling between modules, which I refuse to perpetuate (there's quite enough of that already), or would require the invention of another infrastructure |
|
I'm not quite ready to invent (e.g. an ssi_with_retry object). |
|
|
|
At least the logic that drives this has been pulled out into loncommon. |
|
|
|
|
|
|
|
ssi_with_retries - Does the server side include of a resource. |
|
if the ssi call returns an error we'll retry it up to |
|
the number of times requested by the caller. |
|
If we still have a proble, no text is appended to the |
|
output and we set some global variables. |
|
to indicate to the caller an SSI error occurred. |
|
All of this is supposed to deal with the issues described |
|
in LonCAPA BZ 5631 see: |
|
http://bugs.lon-capa.org/show_bug.cgi?id=5631 |
|
by informing the user that this happened. |
|
|
|
Parameters: |
|
resource - The resource to include. This is passed directly, without |
|
interpretation to lonnet::ssi. |
|
form - The form hash parameters that guide the interpretation of the resource |
|
|
|
retries - Number of retries allowed before giving up completely. |
|
Returns: |
|
On success, returns the rendered resource identified by the resource parameter. |
|
Side Effects: |
|
The following global variables can be set: |
|
ssi_error - If an unrecoverable error occurred this becomes true. |
|
It is up to the caller to initialize this to false |
|
if desired. |
|
ssi_error_resource - If an unrecoverable error occurred, this is the value |
|
of the resource that could not be rendered by the ssi |
|
call. |
|
ssi_error_message - The error string fetched from the ssi response |
|
in the event of an error. |
|
|
|
|
|
=head1 HANDLER SUBROUTINE |
|
|
|
ssi_with_retries() |
|
|
|
=head1 SUBROUTINES |
|
|
|
=over |
|
|
|
=item scantron_get_correction() : |
|
|
|
Builds the interface screen to interact with the operator to fix a |
|
specific error condition in a specific scanline |
|
|
|
Arguments: |
|
$r - Apache request object |
|
$i - number of the current scanline |
|
$scan_record - hash ref as returned from &scantron_parse_scanline() |
|
$scan_config - hash ref as returned from &get_scantron_config() |
|
$line - full contents of the current scanline |
|
$error - error condition, valid values are |
|
'incorrectCODE', 'duplicateCODE', |
|
'doublebubble', 'missingbubble', |
|
'duplicateID', 'incorrectID' |
|
$arg - extra information needed |
|
For errors: |
|
- duplicateID - paper number that this studentID was seen before on |
|
- duplicateCODE - array ref of the paper numbers this CODE was |
|
seen on before |
|
- incorrectCODE - current incorrect CODE |
|
- doublebubble - array ref of the bubble lines that have double |
|
bubble errors |
|
- missingbubble - array ref of the bubble lines that have missing |
|
bubble errors |
|
|
|
=item scantron_get_maxbubble() : |
|
|
|
Returns the maximum number of bubble lines that are expected to |
|
occur. Does this by walking the selected sequence rendering the |
|
resource and then checking &Apache::lonxml::get_problem_counter() |
|
for what the current value of the problem counter is. |
|
|
|
Caches the results to $env{'form.scantron_maxbubble'}, |
|
$env{'form.scantron.bubble_lines.n'}, |
|
$env{'form.scantron.first_bubble_line.n'} and |
|
$env{"form.scantron.sub_bubblelines.n"} |
|
which are the total number of bubble, lines, the number of bubble |
|
lines for response n and number of the first bubble line for response n, |
|
and a comma separated list of numbers of bubble lines for sub-questions |
|
(for optionresponse, matchresponse, and rankresponse items), for response n. |
|
|
|
|
|
=item scantron_validate_missingbubbles() : |
|
|
|
Validates all scanlines in the selected file to not have any |
|
answers that don't have bubbles that have not been verified |
|
to be bubble free. |
|
|
|
=item scantron_process_students() : |
|
|
|
Routine that does the actual grading of the bubble sheet information. |
|
|
|
The parsed scanline hash is added to %env |
|
|
|
Then foreach unskipped scanline it does an &Apache::lonnet::ssi() |
|
foreach resource , with the form data of |
|
|
|
'submitted' =>'scantron' |
|
'grade_target' =>'grade', |
|
'grade_username'=> username of student |
|
'grade_domain' => domain of student |
|
'grade_courseid'=> of course |
|
'grade_symb' => symb of resource to grade |
|
|
|
This triggers a grading pass. The problem grading code takes care |
|
of converting the bubbled letter information (now in %env) into a |
|
valid submission. |
|
|
|
=item scantron_upload_scantron_data() : |
|
|
|
Creates the screen for adding a new bubble sheet data file to a course. |
|
|
|
=item scantron_upload_scantron_data_save() : |
|
|
|
Adds a provided bubble information data file to the course if user |
|
has the correct privileges to do so. |
|
|
|
=item valid_file() : |
|
|
|
Validates that the requested bubble data file exists in the course. |
|
|
|
=item scantron_download_scantron_data() : |
|
|
|
Shows a list of the three internal files (original, corrected, |
|
skipped) for a specific bubble sheet data file that exists in the |
|
course. |
|
|
|
=item scantron_validate_ID() : |
|
|
|
Validates all scanlines in the selected file to not have any |
|
invalid or underspecified student IDs |
|
|
|
=back |
|
|
|
=cut |