Annotation of loncom/interface/lonplacementtest.pm, revision 1.1

1.1     ! raeburn     1: # The LearningOnline Network with CAPA
        !             2: # Handler to manage dependencies for HTML files uploaded directly
        !             3: # to a course.
        !             4: #
        !             5: # $Id: lonplacementtest.pm,v 1.1 2016/03/31 21:57:13 raeburn Exp $
        !             6: #
        !             7: # Copyright Michigan State University Board of Trustees
        !             8: #
        !             9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
        !            10: #
        !            11: # LON-CAPA is free software; you can redistribute it and/or modify
        !            12: # it under the terms of the GNU General Public License as published by
        !            13: # the Free Software Foundation; either version 2 of the License, or
        !            14: # (at your option) any later version.
        !            15: #
        !            16: # LON-CAPA is distributed in the hope that it will be useful,
        !            17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            19: # GNU General Public License for more details.
        !            20: #
        !            21: # You should have received a copy of the GNU General Public License
        !            22: # along with LON-CAPA; if not, write to the Free Software
        !            23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#
        !            24: # /home/httpd/html/adm/gpl.txt
        !            25: #
        !            26: # http://www.lon-capa.org/
        !            27: #
        !            28: #
        !            29: ###############################################################
        !            30: ###############################################################
        !            31: 
        !            32: =pod
        !            33: 
        !            34: =head1 NAME
        !            35: 
        !            36: lonplacementtest - Handler to provide initial screen for student 
        !            37: after log-in and/or role selection for a Placement Test course container
        !            38: which is currently partially completed.
        !            39: 
        !            40: =head1 SYNOPSIS
        !            41: 
        !            42: lonplacementtest provides an interface for the student to choose 
        !            43: whether to continue with an existing, partially completed test,
        !            44: or whether to start a new test. Also provides utility functions
        !            45: used to compute/export scores, and increment the course-wide maxtries
        !            46: parameter for the user, when an instance of a test is complete. 
        !            47: 
        !            48: =head1 DESCRIPTION
        !            49: 
        !            50: This module is used after student log-in and/or role selection
        !            51: for a Placement Test course contained, if there is a current,
        !            52: partially completed version of the test.  The student is prompted
        !            53: to choose whether to continue with the current test or start a
        !            54: new one.
        !            55: 
        !            56: =head1 INTERNAL SUBROUTINES
        !            57: 
        !            58: =over
        !            59: 
        !            60: =item check_completion()
        !            61: 
        !            62: =back
        !            63: 
        !            64: =cut
        !            65: 
        !            66: package Apache::lonplacementtest;
        !            67: 
        !            68: use strict;
        !            69: use Apache::Constants qw(:common :http);
        !            70: use Apache::lonnet;
        !            71: use Apache::loncommon;
        !            72: use Apache::lonhtmlcommon;
        !            73: use Apache::lonnavmaps;
        !            74: use Apache::lonpageflip;
        !            75: use Apache::lonroles;
        !            76: use Apache::lonparmset;
        !            77: use Apache::lonlocal;
        !            78: use LONCAPA qw(:DEFAULT :match);
        !            79: 
        !            80: sub handler {
        !            81:     my $r=shift;
        !            82:     if ($r->header_only) {
        !            83:         &Apache::loncommon::content_type($r,'text/html');
        !            84:         $r->send_http_header;
        !            85:         return OK;
        !            86:     }
        !            87:     if (!$env{'request.course.fn'}) {
        !            88:         # Not in a course.
        !            89:         $env{'user.error.msg'}="/adm/lonplacementtest:bre:0:0:Not in a course";
        !            90:         return HTTP_NOT_ACCEPTABLE;
        !            91:     } elsif ($env{'course.'.$env{'request.course.id'}.'.type'} ne 'Placement') {
        !            92:         # Not in a Placement Test
        !            93:         $env{'user.error.msg'}="/adm/lonplacementtest:bre:0:0:Not in a placement test";
        !            94:         return HTTP_NOT_ACCEPTABLE;
        !            95:     }
        !            96:     &Apache::loncommon::content_type($r,'text/html');
        !            97:     $r->send_http_header;
        !            98:     my ($totalpoints,$incomplete) = &check_completion(undef,undef,1);
        !            99:     if (($incomplete) && ($incomplete < 100) && (!$env{'request.role.adv'})) {
        !           100:         $r->print(&showincomplete($incomplete));
        !           101:     } else {
        !           102:         my $furl = &Apache::lonpageflip::first_accessible_resource();
        !           103:         my $cdesc = $env{'course.'.$env{'request.course.id'}.'.description'};
        !           104:         my $msg = &mt('Entering [_1] ...',$cdesc);
        !           105:         &Apache::lonroles::redirect_user($r, &mt('Entering [_1]',$cdesc),$furl, $msg);
        !           106:     }
        !           107:     return OK;
        !           108: }
        !           109: 
        !           110: sub check_completion {
        !           111:     my ($makenew,$map,$recursive) = @_;
        !           112:     my $navmap = Apache::lonnavmaps::navmap->new();
        !           113:     return unless (ref($navmap));
        !           114:     my @resources = $navmap->retrieveResources($map,
        !           115:                                                sub { $_[0]->is_problem() },$recursive);
        !           116:     my $currmax = 0;
        !           117:     my $totalpoints = 0;
        !           118:     my $totaldone = 0;
        !           119:     my $totalnotdone = 0;
        !           120:     my $incomplete;
        !           121:     if (@resources) {
        !           122:         my $firstsymb = $resources[0]->symb();
        !           123:         my %bytitle;
        !           124:         foreach my $res (@resources) {
        !           125:             my $currsymb = $res->symb();
        !           126:             my $title = $res->compTitle;
        !           127:             unless (exists($bytitle{$title})) {
        !           128:                 $bytitle{$title} = 0;
        !           129:             }
        !           130:             my $notdone = 0;
        !           131:             my $done = 0;
        !           132:             my %storetries;
        !           133:             my $points = 0;
        !           134:             foreach my $part (@{$res->parts()}) {
        !           135:                 my $tries = $res->tries($part);
        !           136:                 my $maxtries = $res->maxtries($part);
        !           137:                 if ($currmax < $maxtries) {
        !           138:                     $currmax = $maxtries;
        !           139:                 }
        !           140:                 if ($tries < $maxtries) {
        !           141:                     $notdone ++;
        !           142:                     my $tries = $res->tries($part);
        !           143:                     my @response_ids = $res->responseIds($part);
        !           144:                     if (@response_ids) {
        !           145:                         foreach my $id (@response_ids) {
        !           146:                             $storetries{"resource.$part.$id.awarded"}=0;
        !           147:                             $storetries{"resource.$part.$id.awarddetail"}='ASSIGNED_SCORE';
        !           148:                         }
        !           149:                         $storetries{"resource.$part.tries"}=$maxtries;
        !           150:                         $storetries{"resource.$part.solved"}='incorrect_by_override';
        !           151:                         $storetries{"resource.$part.award"}='ASSIGNED_SCORE';
        !           152:                         $storetries{"resource.$part.awarded"}=0;
        !           153:                     }
        !           154:                 } else {
        !           155:                     my $awarded = $res->awarded($part);
        !           156:                     my $weight = $res->weight($part);
        !           157:                     $points += $awarded * $weight;
        !           158:                     $done ++;
        !           159:                 }
        !           160:             }
        !           161:             if ($notdone) {
        !           162:                 $totalnotdone += $notdone;
        !           163:                 if ($makenew && keys(%storetries)) {
        !           164:                     my $result=&Apache::lonnet::cstore(\%storetries,$currsymb,$env{'request.course.id'},
        !           165:                                                        $env{'user.domain'},$env{'user.name'});
        !           166:                 }
        !           167:             }
        !           168:             if ($done) {
        !           169:                 $totaldone += $done;
        !           170:             }
        !           171:             $bytitle{$title} += $points;
        !           172:             $totalpoints += $points;
        !           173:         }
        !           174:         if ($makenew) {
        !           175:             my $newmax = $currmax + 1;
        !           176:             my $result =
        !           177:                 &Apache::lonparmset::storeparm_by_symb_inner($firstsymb,'0_maxtries',
        !           178:                                                              4,$newmax,'int_pos',
        !           179:                                                              $env{'user.name'},
        !           180:                                                              $env{'user.domain'});
        !           181:             my %grades = (
        !           182:                              uname   => $env{'user.name'},
        !           183:                              domain  => $env{'user.domain'},
        !           184:                              total   => $totalpoints,
        !           185:                              bytitle => \%bytitle,
        !           186:                          );
        !           187:             my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
        !           188:             my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
        !           189:             if (($cnum ne '') && ($cdom ne '')) {
        !           190:                 &Apache::lonnet::auto_export_grades($cnum,$cdom,\%grades);
        !           191:             }
        !           192:         }
        !           193:     }
        !           194:     my $totalparts = $totalnotdone + $totaldone;
        !           195:     if (($totalparts) && ($totalnotdone)) {
        !           196:         if (!$totaldone) {
        !           197:             $incomplete = 100;
        !           198:         } else {
        !           199:             my $undonepct = (100*$totalnotdone)/$totalparts;
        !           200:             $incomplete = sprintf("%0d",$undonepct);
        !           201:         }
        !           202:     }
        !           203:     return ($totalpoints,$incomplete);
        !           204: }
        !           205: 
        !           206: sub showresult {
        !           207:     my ($complete) = @_;
        !           208:     my ($score) = &Apache::lonplacementtest::check_completion(1,undef,1);
        !           209:     my %aclt = &test_action_text();
        !           210:     my $brcrum = [{'href' => '/adm/flip?postdata=firstres%3a',
        !           211:                    'text' => 'Test Status'},];
        !           212:     my $output = &Apache::loncommon::start_page('Placement Test Completed',
        !           213:                                           undef,{bread_crumbs=>$brcrum});
        !           214:     if ($complete) {
        !           215:         $output .= '<p class="LC_info">'.&mt('Test is complete').'</p>';
        !           216:     }
        !           217:     return $output
        !           218:           .'<p>'.&mt('You scored [quant,_1,point].',$score).'</p>'
        !           219:           .&Apache::lonhtmlcommon::actionbox(
        !           220:               ['<a href="/adm/flip?postdata=firstres%3a">'.$aclt{'newt'}.'</a></li>',
        !           221:                '<a href="/adm/logout">'.$aclt{'exit'}.'</a></li>',
        !           222:               ])
        !           223:           .&Apache::loncommon::end_page();
        !           224: }
        !           225: 
        !           226: sub showincomplete {
        !           227:     my ($incomplete) = @_;
        !           228:     my %aclt = &test_action_text();
        !           229:     if ($incomplete == 100) {
        !           230:         my $brcrum = [{'href' => '/adm/flip?postdata=firstres%3a',
        !           231:                        'text' => 'Test Status'},];
        !           232:         return &Apache::loncommon::start_page('Placement Test Unattempted',
        !           233:                                               undef,{bread_crumbs=>$brcrum})
        !           234:               .'<p class="LC_warning">'.&mt('Your Placement Test is incomplete.').'<p></p>'
        !           235:               .&mt('Currently, you have not submitted any answers for any of the questions.')
        !           236:               .'</p>'
        !           237:               .&Apache::lonhtmlcommon::actionbox(
        !           238:                   ['<a href="/adm/flip?postdata=firstres%3a">'.$aclt{'begin'}.'</a></li>',
        !           239:                    '<a href="/adm/logout">'.$aclt{'exit'}.'</a></li>',
        !           240:                   ])
        !           241:               .&Apache::loncommon::end_page(); 
        !           242:     } elsif ($incomplete) {
        !           243:         my $brcrum = [{'href' => '/adm/flip?postdata=endplacement%3a',
        !           244:                        'text' => 'Test Status'},];
        !           245:         return &Apache::loncommon::start_page('Incomplete Placement Test',
        !           246:                                               undef,{bread_crumbs=>$brcrum})  
        !           247:               .'<p class="LC_warning">'.&mt('Your Placement Test is incomplete.').'<p></p>'
        !           248:               .&mt('Currently, you have not provided an answer for [_1]% of the questions.',$incomplete)
        !           249:               .'</p>'
        !           250:               .&Apache::lonhtmlcommon::actionbox(
        !           251:                   ['<a href="/adm/flip?postdata=endplacement%3a">'.$aclt{'endt'}.'</a></li>',
        !           252:                    '<a href="/adm/flip?postdata=firstanswerable%3a">'.$aclt{'comp'}.'</a></li>',
        !           253:                    '<a href="/adm/logout">'.$aclt{'exit'}.'</a></li>',
        !           254:                   ])
        !           255:               .&Apache::loncommon::end_page();
        !           256:     }
        !           257: }
        !           258: 
        !           259: sub test_action_text {
        !           260:     return &Apache::lonlocal::texthash(
        !           261:                                         'exit'  => 'Logout',
        !           262:                                         'newt'  => 'Start a new test',
        !           263:                                         'endt'  => 'Mark test as completed',
        !           264:                                         'comp'  => 'Go to first unanswered question',
        !           265:                                         'begin' => 'Go to start',
        !           266:                                       );
        !           267: }
        !           268: 
        !           269: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>