[LON-CAPA-cvs] cvs: loncom /interface lonnavmaps.pm

bowersj2 lon-capa-cvs@mail.lon-capa.org
Fri, 16 May 2003 14:17:09 -0000


This is a MIME encoded message

--bowersj21053094629
Content-Type: text/plain

bowersj2		Fri May 16 10:17:09 2003 EDT

  Modified files:              
    /loncom/interface	lonnavmaps.pm 
  Log:
  * Fix a bug in lonnavmaps where it doesn't honor hidden for students. (!)
  
  * If for some reason the navmaps displays nothing when the NAV button
    is clicked, a reassuring message is printed that the course is empty.
    ("Reassuring" vs. mysterious, silent failure.)
  
  * Implemented my suggestion that we only display currently uncompleted
    homework, because with the fix for detecting empty folders, it's
    easy. I suggest we run both this and "jump to next homework problem"
    for the summer, and evaluate which the students are using, and whether
    "show only homework" is causing conceptual problems at that time.
  
  
--bowersj21053094629
Content-Type: text/plain
Content-Disposition: attachment; filename="bowersj2-20030516101709.txt"

Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.190 loncom/interface/lonnavmaps.pm:1.191
--- loncom/interface/lonnavmaps.pm:1.190	Wed May 14 16:16:56 2003
+++ loncom/interface/lonnavmaps.pm	Fri May 16 10:17:08 2003
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.190 2003/05/14 20:16:56 bowersj2 Exp $
+# $Id: lonnavmaps.pm,v 1.191 2003/05/16 14:17:08 bowersj2 Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -200,8 +200,10 @@
         }
     }
 
+    my $jumpToFirstHomework = 0;
     # Check to see if the student is jumping to next open, do-able problem
     if ($ENV{QUERY_STRING} eq 'jumpToFirstHomework') {
+        $jumpToFirstHomework = 1;
         # Find the next homework problem that they can do.
         my $iterator = $navmap->getIterator(undef, undef, undef, 1);
         my $depth = 1;
@@ -216,9 +218,7 @@
 
             if (ref($curRes) && $curRes->is_problem()) {
                 my $status = $curRes->status();
-                if (($status == $curRes->OPEN || 
-                     $status == $curRes->TRIES_LEFT()) &&
-                    $curRes->getCompletionStatus() != $curRes->ATTEMPTED()) {
+                if ($curRes->completable()) {
                     $problemRes = $curRes;
                     $foundDoableProblem = 1;
 
@@ -246,15 +246,45 @@
                   "Go To My First Homework Problem</a><br />");
     }
 
-    # renderer call
-    my $render = render({ 'cols' => [0,1,2,3],
-                          'url' => '/adm/navmaps',
-                          'navmap' => $navmap,
-                          'suppressNavmap' => 1,
-                          'r' => $r});
+    my $suppressEmptySequences = 0;
+    my $filterFunc = undef;
+    # Display only due homework.
+    my $showOnlyHomework = 0;
+    if ($ENV{QUERY_STRING} eq 'showOnlyHomework') {
+        $showOnlyHomework = 1;
+        $suppressEmptySequences = 1;
+        $filterFunc = sub { my $res = shift; 
+                            return $res->completable() || $res->is_sequence();
+                        };
+        $r->print("<p><font size='+2'>Uncompleted Homework</font></p>");
+        $ENV{'form.filter'} = '';
+        $ENV{'form.condition'} = 1;
+    } else {
+        $r->print("<a href='navmaps?showOnlyHomework'>" .
+                  "Show Only Uncompleted Homework</a><br />");
+    }
 
+    # renderer call
+    my $renderArgs = { 'cols' => [0,1,2,3],
+                       'url' => '/adm/navmaps',
+                       'navmap' => $navmap,
+                       'suppressNavmap' => 1,
+                       'suppressEmptySequences' => $suppressEmptySequences,
+                       'filterFunc' => $filterFunc,
+                       'r' => $r};
+    my $render = render($renderArgs);
     $navmap->untieHashes();
 
+    # If no resources were printed, print a reassuring message so the
+    # user knows there was no error.
+    if ($renderArgs->{'counter'} == 0) {
+        if ($showOnlyHomework) {
+            $r->print("<p><font size='+1'>All homework is currently completed.</font></p>");
+        } else { # both jumpToFirstHomework and normal use the same: course must be empty
+            $r->print("<p><font size='+1'>This course is empty.</font></p>");
+        }
+    }
+
     $r->print("</body></html>");
     $r->rflush();
 
@@ -1041,6 +1071,19 @@
         }
     }
 
+    # Filter: Remember filter function and add our own filter: Refuse
+    # to show hidden resources unless the user can see them.
+    my $userCanSeeHidden = advancedUser();
+    my $filterFunc = setDefault($args->{'filterFunc'},
+                                sub {return 1;});
+    if (!$userCanSeeHidden) {
+        # Without renaming the filterfunc, the server seems to go into
+        # an infinite loop
+        my $oldFilterFunc = $filterFunc;
+        $filterFunc = sub { my $res = shift; return !$res->randomout() && 
+                                &$oldFilterFunc($res);};
+    }
+
     my $condition = 0;
     if ($ENV{'form.condition'}) {
         $condition = 1;
@@ -1137,6 +1180,8 @@
     }
     
     # (re-)Locate the jump point, if any
+    # Note this does not take filtering or hidden into account... need
+    # to be fixed?
     my $mapIterator = $navmap->getIterator(undef, undef, $filterHash, 0);
     my $depth = 1;
     $mapIterator->next();
@@ -1169,8 +1214,6 @@
     my $printKey = $args->{'printKey'};
     my $printCloseAll = $args->{'printCloseAll'};
     if (!defined($printCloseAll)) { $printCloseAll = 1; }
-    my $filterFunc = setDefault($args->{'filterFunc'},
-                                sub {return 1;});
     
     # Print key?
     if ($printKey) {
@@ -1303,8 +1346,6 @@
             next;
         }
 
-        $args->{'counter'}++;
-
         # If this has been filtered out, continue on
         if (!(&$filterFunc($curRes))) {
             $args->{'isNewBranch'} = 0; # Don't falsely remember this
@@ -1322,6 +1363,8 @@
             next;
         }
 
+        $args->{'counter'}++;
+
         # Does it have multiple parts?
         $args->{'multipart'} = 0;
         $args->{'condensed'} = 0;
@@ -3177,7 +3220,7 @@
 Returns the number of parts of the problem a student can answer. Thus,
 for single part problems, returns 1. For multipart, it returns the
 number of parts in the problem, not including psuedo-part 0. Thus,
-B<parts> may return an array with fewer parts in it then countParts
+B<parts> may return an array with more parts in it then countParts
 might lead you to believe.
 
 =item * B<responseType>($part):
@@ -3206,16 +3249,18 @@
     my $self = shift;
     
     my $parts = $self->parts();
-    my $delta = 0;
-    for my $part (@$parts) {
-        if ($part eq '0') { $delta--; }
-    }
+
+    # If I left this here, then it's not necessary.
+    #my $delta = 0;
+    #for my $part (@$parts) {
+    #    if ($part eq '0') { $delta--; }
+    #}
 
     if ($self->{RESOURCE_ERROR}) {
         return 0;
     }
 
-    return scalar(@{$parts}) + $delta;
+    return scalar(@{$parts}); # + $delta;
 }
 
 sub responseType {
@@ -3532,7 +3577,9 @@
 Along with directly returning the date or completion status, the
 resource object includes a convenience function B<status>() that will
 combine the two status tidbits into one composite status that can
-represent the status of the resource as a whole. The precise logic is
+represent the status of the resource as a whole. This method represents
+the concept of the thing we want to display to the user on the nav maps
+screen, which is a combination of completion and open status. 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): In addition to the return values that match
@@ -3672,6 +3719,48 @@
 
     # Otherwise, it's untried and open
     return OPEN; 
+}
+
+=pod
+
+B<Completable>
+
+The completable method represents the concept of I<whether the student can
+currently do the problem>. If the student can do the problem, which means
+that it is open, there are tries left, and if the problem is manually graded
+or the grade is suppressed via problemstatus, the student has not tried it
+yet, then the method returns 1. Otherwise, it returns 0, to indicate that 
+either the student has tried it and there is no feedback, or that for
+some reason it is no longer completable (not open yet, successfully completed,
+out of tries, etc.). As an example, this is used as the filter for the
+"Uncompleted Homework" option for the nav maps.
+
+If this does not quite meet your needs, do not fiddle with it (unless you are
+fixing it to better match the student's conception of "completable" because
+it's broken somehow)... make a new method.
+
+=cut
+
+sub completable {
+    my $self = shift;
+    if (!$self->is_problem()) { return 0; }
+    my $partCount = $self->countParts();
+
+    foreach my $part (@{$self->parts()}) {
+        if ($part eq '0' && $partCount != 1) { next; }
+        my $status = $self->status($part);
+        # "If any of the parts are open, or have tries left (implies open),
+        # and it is not "attempted" (manually graded problem), it is
+        # not "complete"
+        if (!(($status == OPEN() || $status == TRIES_LEFT()) 
+              && $self->getCompletionStatus($part) != ATTEMPTED()
+              && $status != ANSWER_SUBMITTED())) {
+            return 0;
+        }
+    }
+        
+    # If all the parts were complete, so was this problem.
+    return 1;
 }
 
 =pod

--bowersj21053094629--