/** * Do we have all the necessary inputs to execute one of the potential response trees? * @param stack_potentialresponse_tree $prt the tree in question. * @param array $response the response. * @param bool $acceptvalid if this is true, then we will grade things even * if the corresponding inputs are only VALID, and not SCORE. * @return bool can this PRT be executed for that response. */ protected function can_execute_prt(stack_potentialresponse_tree $prt, $response, $acceptvalid) { // The only way to find out is to actually try evaluating it. This calls // has_necessary_prt_inputs, and then does the computation, which ensures // there are no CAS errors. $result = $this->get_prt_result($prt->get_name(), $response, $acceptvalid); return null !== $result->valid && !$result->errors; }
/** * Helper method to get the list of inputs required by a PRT, given the current * state of the form. * @param string $prtname the name of a PRT. * @return array list of inputs used by this PRT. */ protected function get_inputs_used_by_prt($prtname) { // Needed for questions with no inputs, (in particular blank starting questions). if (!property_exists($this->question, 'inputs')) { return array(); } if (is_null($this->question->inputs)) { return array(); } $inputs = $this->question->inputs; $inputkeys = array(); if (is_array($inputs)) { foreach ($inputs as $input) { $inputkeys[] = $input->name; } } else { return array(); } // TODO fix this. At the moment it only considers the data from the unedited // question. We should take into account any changes made since the // form was first shown, for example adding or removing nodes, or changing // the things they compare. However, it is not critical. // If we are creating a new question, or if we add a new prt in the // question stem, then the PRT will not yet exist, so return an empty array. if (is_null($this->question->prts) || !array_key_exists($prtname, $this->question->prts)) { return array(); } $prt = $this->question->prts[$prtname]; $prtnodes = array(); foreach ($prt->nodes as $name => $node) { $sans = new stack_cas_casstring($node->sans); $tans = new stack_cas_casstring($node->tans); $prtnode = new stack_potentialresponse_node($sans, $tans, $node->answertest, $node->testoptions); $prtnode->add_branch(1, '+', 0, '', -1, $node->truefeedback, $node->truefeedbackformat, ''); $prtnode->add_branch(0, '+', 0, '', -1, $node->falsefeedback, $node->falsefeedbackformat, ''); $prtnodes[$name] = $prtnode; } $feedbackvariables = new stack_cas_keyval($prt->feedbackvariables, null, 0, 't'); $potentialresponsetree = new stack_potentialresponse_tree('', '', false, 0, $feedbackvariables->get_session(), $prtnodes, $prt->firstnodename); return $potentialresponsetree->get_required_variables($inputkeys); }
public function test_do_test_3() { // Nontrivial use of the feeback variables. // Error in authoring ends up in loop. STACK should bail. $options = new stack_options(); $seed = 12345; $questionvars = new stack_cas_keyval('n:3; p:(x+1)^n; ta:p;', $options, $seed, 't'); // Feeback variables. $cstrings = array('sa1:sans', 'sa2:expand(sans)'); foreach ($cstrings as $s) { $cs = new stack_cas_casstring($s); $cs->get_valid('t'); $s1[] = $cs; } $feedbackvars = new stack_cas_session($s1, $options, $seed); $feedbackvars->get_valid(); // Define the tree itself. $sans = new stack_cas_casstring('sa1'); $sans->get_valid('t'); $tans = new stack_cas_casstring('ta'); $tans->get_valid('t'); $node = new stack_potentialresponse_node($sans, $tans, 'AlgEquiv', '', true); $node->add_branch(0, '=', 0, '', -1, 'Test 1 false. Look: \\[@(sa1)^2@ \\neq @(sa2)^2@\\]', FORMAT_HTML, '1-0-0'); $node->add_branch(1, '=', 1, '', 1, 'Test 1 true. ', FORMAT_HTML, '1-0-1'); $potentialresponses[] = $node; $sans = new stack_cas_casstring('sa2'); $sans->get_valid('t'); $tans = new stack_cas_casstring('ta'); $tans->get_valid('t'); $node = new stack_potentialresponse_node($sans, $tans, 'FacForm', 'x', true); $node->add_branch(0, '-', 0.7, '', 0, 'Test 2 false.', FORMAT_HTML, '1-1-0'); $node->add_branch(1, '+', 1, '', 3, 'Test 2 true', FORMAT_HTML, '1-1-1'); $potentialresponses[] = $node; $tree = new stack_potentialresponse_tree('', '', true, 5, $feedbackvars, $potentialresponses, 0); // Some data from students. $answers = array('sans' => '(x+1)^3'); $result = $tree->evaluate_response($questionvars->get_session(), $options, $answers, $seed); $this->assertTrue($result->valid); $this->assertEquals('', $result->errors); $this->assertEquals(0.3, $result->score); $this->assertEquals(0, $result->penalty); $this->assertEquals(2, count($result->feedback)); $this->assertEquals('Test 1 true.', $result->feedback[0]->feedback); $this->assertEquals('Test 2 false.', $result->feedback[1]->feedback); $this->assertEquals(array('1-0-1', 'ATFacForm_notfactored.', '1-1-0', '[PRT-CIRCULARITY]=0'), $result->answernotes); $this->assertEquals(array('sa1', 'ta'), $tree->get_required_variables(array('sa1', 'sa3', 'ta', 'ssa1', 'a1', 't'))); }