--- loncom/interface/lonnavmaps.pm 2003/04/24 18:18:38 1.181 +++ loncom/interface/lonnavmaps.pm 2003/05/12 19:22:39 1.186 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.181 2003/04/24 18:18:38 bowersj2 Exp $ +# $Id: lonnavmaps.pm,v 1.186 2003/05/12 19:22:39 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -71,7 +71,8 @@ my %statusIconMap = $resObj->TRIES_LEFT => 'navmap.open.gif', $resObj->INCORRECT => 'navmap.wrong.gif', $resObj->OPEN => 'navmap.open.gif', - $resObj->ATTEMPTED => 'navmap.open.gif' ); + $resObj->ATTEMPTED => 'navmap.open.gif', + $resObj->ANSWER_SUBMITTED => '' ); my %iconAltTags = ( 'navmap.correct.gif' => 'Correct', @@ -199,6 +200,52 @@ sub real_handler { } } + # Check to see if the student is jumping to next open, do-able problem + if ($ENV{QUERY_STRING} eq 'jumpToFirstHomework') { + # Find the next homework problem that they can do. + my $iterator = $navmap->getIterator(undef, undef, undef, 1); + my $depth = 1; + $iterator->next(); + my $curRes = $iterator->next(); + my $foundDoableProblem = 0; + my $problemRes; + + while ($depth > 0 && !$foundDoableProblem) { + if ($curRes == $iterator->BEGIN_MAP()) { $depth++; } + if ($curRes == $iterator->END_MAP()) { $depth--; } + + if (ref($curRes) && $curRes->is_problem()) { + my $status = $curRes->status(); + if (($status == $curRes->OPEN || + $status == $curRes->TRIES_LEFT()) && + $curRes->getCompletionStatus() != $curRes->ATTEMPTED()) { + $problemRes = $curRes; + $foundDoableProblem = 1; + + # Pop open all previous maps + my $stack = $iterator->getStack(); + pop @$stack; # last resource in the stack is the problem + # itself, which we don't need in the map stack + my @mapPcs = map {$_->map_pc()} @$stack; + $ENV{'form.filter'} = join(',', @mapPcs); + + # Mark as both "here" and "jump" + $ENV{'form.postsymb'} = $curRes->symb(); + } + } + } continue { + $curRes = $iterator->next(); + } + + # If we found no problems, print a note to that effect. + if (!$foundDoableProblem) { + $r->print("All homework assignments have been completed.

"); + } + } else { + $r->print("" . + "Go To My First Homework Problem
"); + } + # renderer call my $render = render({ 'cols' => [0,1,2,3], 'url' => '/adm/navmaps', @@ -271,7 +318,9 @@ sub getDescription { my $part = shift; my $status = $res->status($part); - if ($status == $res->NETWORK_FAILURE) { return ""; } + if ($status == $res->NETWORK_FAILURE) { + return "Having technical difficulties; please check status later"; + } if ($status == $res->NOTHING_SET) { return "Not currently assigned."; } @@ -317,6 +366,9 @@ sub getDescription { return "No due date $triesString"; } } + if ($status == $res->ANSWER_SUBMITTED) { + return 'Answer submitted'; + } } # Convenience function, so others can use it: Is the problem due in less then @@ -1472,15 +1524,13 @@ sub init { unless ((time-$courserdatas{$cid.'.last_cache'})<240) { my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum. ':resourcedata',$chome); - if ($reply!~/^error\:/) { + # Check for network failure + if ( $reply =~ /no.such.host/i || $reply =~ /con_lost/i) { + $self->{NETWORK_FAILURE} = 1; + } elsif ($reply!~/^error\:/) { $courserdatas{$cid}=$reply; $courserdatas{$cid.'.last_cache'}=time; } - # check to see if network failed - elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i ) - { - $self->{NETWORK_FAILURE} = 1; - } } foreach (split(/\&/,$courserdatas{$cid})) { my ($name,$value)=split(/\=/,$_); @@ -2753,7 +2803,10 @@ sub is_sequence { sub parmval { my $self = shift; my $what = shift; - my $part = shift || "0"; + my $part = shift; + if (!defined($part)) { + $part = '0'; + } return $self->{NAV_MAP}->parmval($part.'.'.$what, $self->symb()); } @@ -2927,6 +2980,10 @@ sub opendate { } return $self->parmval("opendate"); } +sub problemstatus { + (my $self, my $part) = @_; + return $self->parmval("problemstatus", $part); +} sub sig { (my $self, my $part) = @_; return $self->parmval("sig", $part); @@ -3069,7 +3126,16 @@ sub countParts { return scalar(@{$parts}) + $delta; } -# Private function: Extracts the parts information and saves it +sub partType { + my $self = shift; + my $part = shift; + + $self->extractParts(); + return $self->{PART_TYPE}->{$part}; +} + +# Private function: Extracts the parts information, both part names and +# part types, and saves it sub extractParts { my $self = shift; @@ -3086,15 +3152,16 @@ sub extractParts { if (!$metadata) { $self->{RESOURCE_ERROR} = 1; $self->{PARTS} = []; + $self->{PART_TYPE} = {}; return; } foreach (split(/\,/,$metadata)) { if ($_ =~ /^part_(.*)$/) { my $part = $1; - # This floods the logs - #if (defined($parts{$part})) { - # Apache::lonnet::logthis("$part multiply defined in metadata for " . $self->symb()); - # } + # This floods the logs if it blows up + if (defined($parts{$part})) { + Apache::lonnet::logthis("$part multiply defined in metadata for " . $self->symb()); + } # check to see if part is turned off. @@ -3310,7 +3377,7 @@ sub queryRestoreHash { my $self = shift; my $hashentry = shift; my $part = shift; - $part = "0" if (!defined($part)); + $part = "0" if (!defined($part) || $part eq ''); return $self->NETWORK_FAILURE if ($self->{NAV_MAP}->{NETWORK_FAILURE}); $self->getReturnHash(); @@ -3328,7 +3395,10 @@ combine the two status tidbits into one represent the status of the resource as a whole. The precise logic is documented in the comments of the status method. The following results may be returned, all available as methods on the resource object -($res->NETWORK_FAILURE): +($res->NETWORK_FAILURE): In addition to the return values that match +the date or completion status, this function can return "ANSWER_SUBMITTED" +if that problemstatus parameter value is set to No, suppressing the +incorrect/correct feedback. =over 4 @@ -3387,11 +3457,16 @@ The item is open and not yet tried. The problem has been attempted. +=item * B: + +An answer has been submitted, but the student should not see it. + =back =cut -sub TRIES_LEFT { return 10; } +sub TRIES_LEFT { return 20; } +sub ANSWER_SUBMITTED { return 21; } sub status { my $self = shift; @@ -3406,10 +3481,12 @@ sub status { if ($completionStatus == NETWORK_FAILURE) { return NETWORK_FAILURE; } + my $suppressFeedback = lc($self->parmval("problemstatus", $part)) eq 'no'; + # There are a few whole rows we can dispose of: if ($completionStatus == CORRECT || $completionStatus == CORRECT_BY_OVERRIDE ) { - return CORRECT; + return $suppressFeedback? ANSWER_SUBMITTED : CORRECT; } if ($completionStatus == ATTEMPTED) { @@ -3450,7 +3527,7 @@ sub status { if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { return TRIES_LEFT; } - return INCORRECT; # otherwise, return orange; student can't fix this + return $suppressFeedback ? ANSWER_SUBMITTED : INCORRECT; # otherwise, return orange; student can't fix this } # Otherwise, it's untried and open