コード例 #1
0
 /**
  * This function actually traverses the tree and generates outcomes.
  *
  * @param stack_cas_session $questionvars the question varaibles.
  * @param stack_options $options
  * @param array $answers name => value the student response.
  * @param int $seed the random number seed.
  * @return stack_potentialresponse_tree_state the result.
  */
 public function evaluate_response(stack_cas_session $questionvars, $options, $answers, $seed)
 {
     if (empty($this->nodes)) {
         throw new stack_exception('stack_potentialresponse_tree: evaluate_response ' . 'attempting to traverse an empty tree. Something is wrong here.');
     }
     $localoptions = clone $options;
     $localoptions->set_option('simplify', $this->simplify);
     $cascontext = $this->create_cas_context_for_evaluation($questionvars, $localoptions, $answers, $seed);
     $results = new stack_potentialresponse_tree_state($this->value, true, 0, 0);
     // Traverse the tree.
     $nodekey = $this->firstnode;
     $visitednodes = array();
     while ($nodekey != -1) {
         if (!array_key_exists($nodekey, $this->nodes)) {
             throw new stack_exception('stack_potentialresponse_tree: ' . 'evaluate_response: attempted to jump to a potential response ' . 'which does not exist in this question.  This is a question ' . 'authoring/validation problem.');
         }
         if (array_key_exists($nodekey, $visitednodes)) {
             $results->add_answernote('[PRT-CIRCULARITY]=' . $nodekey);
             break;
         }
         $visitednodes[$nodekey] = true;
         $nodekey = $this->nodes[$nodekey]->traverse($results, $nodekey, $cascontext, $localoptions);
         if ($results->_errors) {
             break;
         }
     }
     // Make sure these are PHP numbers.
     $results->_score = $results->_score + 0;
     $results->_penalty = $results->_penalty + 0;
     // Restrict score to be between 0 and 1.
     $results->_score = min(max($results->_score, 0), 1);
     // From a strictly logical point of view the 'score' and the 'penalty' are independent.
     // Hence, this clause belongs in the question behaviour.
     // From a practical point of view, it is confusing/off-putting when testing to see "score=1, penalty=0.1".
     // Why does this correct attempt attract a penalty?  So, this is a unilateral decision:
     // If the score is 1 there is never a penalty.
     if ($results->_score > 0.99999995) {
         $results->_penalty = 0;
     }
     if ($results->errors) {
         $results->_score = null;
         $results->_penalty = null;
     }
     $results->set_cas_context($cascontext, $seed);
     return $results;
 }
コード例 #2
0
 /**
  * Actually execute the test for this node.
  */
 public function do_test($nsans, $ntans, $ncasopts, $options, stack_potentialresponse_tree_state $results)
 {
     if (false === $ncasopts) {
         $ncasopts = $this->atoptions;
     }
     $at = new stack_ans_test_controller($this->answertest, $nsans, $ntans, $options, $ncasopts);
     $at->do_test();
     $testpassed = $at->get_at_mark();
     if ($testpassed) {
         $resultbranch = $this->branches[1];
         $branchname = 'prtnodetruefeedback';
     } else {
         $resultbranch = $this->branches[0];
         $branchname = 'prtnodefalsefeedback';
     }
     if ($at->get_at_answernote()) {
         $results->add_answernote($at->get_at_answernote());
     }
     if ($resultbranch['answernote']) {
         $results->add_answernote($resultbranch['answernote']);
     }
     // If the answer test is running in quiet mode we suppress any
     // automatically generated feedback from the answertest itself.
     if (!$this->quiet && $at->get_at_feedback()) {
         $results->add_feedback($at->get_at_feedback());
     }
     if ($resultbranch['feedback']) {
         $results->add_feedback($resultbranch['feedback'], $resultbranch['feedbackformat'], $branchname, $this->nodeid);
     }
     $results->_valid = $results->_valid && $at->get_at_valid();
     $results->_score = $this->update_score($results->_score, $resultbranch);
     if ($resultbranch['penalty'] !== '') {
         $results->_penalty = $resultbranch['penalty'];
     }
     $results->_errors .= $at->get_at_errors();
     return $resultbranch['nextnode'];
 }