/** * * * @return bool * @access public */ public function do_test() { if ('' == trim($this->sanskey)) { $this->aterror = stack_string('TEST_FAILED', array('errors' => stack_string("AT_EmptySA"))); $this->atfeedback = stack_string('TEST_FAILED', array('errors' => stack_string("AT_EmptySA"))); $this->atansnote = $this->casfunction . 'TEST_FAILED:Empty SA.'; $this->atmark = 0; $this->atvalid = false; return null; } if ('' == trim($this->tanskey)) { $this->aterror = stack_string('TEST_FAILED', array('errors' => stack_string("AT_EmptyTA"))); $this->atfeedback = stack_string('TEST_FAILED', array('errors' => stack_string("AT_EmptyTA"))); $this->atansnote = $this->casfunction . 'TEST_FAILED:Empty TA.'; $this->atmark = 0; $this->atvalid = false; return null; } if ($this->processcasoptions) { if (null == $this->atoption or '' == $this->atoption) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => stack_string("AT_MissingOptions"))); $this->atansnote = 'STACKERROR_OPTION.'; $this->atmark = 0; $this->atvalid = false; return null; } else { // Validate with teacher privileges, strict syntax & no automatically adding stars. $ct = new stack_cas_casstring($this->atoption); if (!$ct->get_valid('t', true, 1)) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => '')); $this->atfeedback .= stack_string('AT_InvalidOptions', array('errors' => $ct->get_errors())); $this->atansnote = 'STACKERROR_OPTION.'; $this->atmark = 0; $this->atvalid = false; return null; } } $atopt = $this->atoption; $ta = "[{$this->tanskey},{$atopt}]"; } else { $ta = $this->tanskey; } // Sort out options. if (null === $this->options) { $this->options = new stack_options(); } if (!(null === $this->simp)) { $this->options->set_option('simplify', $this->simp); } $cascommands = array(); $cascommands[] = "STACKSA:{$this->sanskey}"; $cascommands[] = "STACKTA:{$ta}"; $cascommands[] = "result:StackReturn({$this->casfunction}(STACKSA,STACKTA))"; $cts = array(); foreach ($cascommands as $com) { $cs = new stack_cas_casstring($com); $cs->get_valid('t', true, 0); $cts[] = $cs; } $session = new stack_cas_session($cts, $this->options, 0); $session->instantiate(); $this->debuginfo = $session->get_debuginfo(); if ('' != $session->get_errors_key('STACKSA')) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => $session->get_errors_key('STACKSA'))); $this->atansnote = $this->casfunction . '_STACKERROR_SAns.'; $this->atmark = 0; $this->atvalid = false; return null; } if ('' != $session->get_errors_key('STACKTA')) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => $session->get_errors_key('STACKTA'))); $this->atansnote = $this->casfunction . '_STACKERROR_TAns.'; $this->atmark = 0; $this->atvalid = false; return null; } $sessionvars = $session->get_session(); $result = $sessionvars[2]; if ('' != $result->get_errors()) { $this->aterror = 'TEST_FAILED'; if ('' != trim($result->get_feedback())) { $this->atfeedback = $result->get_feedback(); } else { $this->atfeedback = stack_string('TEST_FAILED', array('errors' => $result->get_errors())); } $this->atansnote = trim($result->get_answernote()); $this->atmark = 0; $this->atvalid = false; return null; } $this->atansnote = trim($result->get_answernote()); // Convert the Maxima string 'true' to PHP true. if ('true' == $result->get_value()) { $this->atmark = 1; } else { $this->atmark = 0; } $this->atfeedback = $result->get_feedback(); $this->atvalid = $result->get_valid(); if ($this->atmark) { return true; } else { return false; } }
/** * Traverse this node, updating the results array that is used by * {@link stack_potentialresponse_tree::evaluate_response()}. * * @param stack_potentialresponse_tree_state $results to be updated. * @param int $key the index of this node. * @param stack_cas_session $cascontext the CAS context that holds all the relevant variables. * @param stack_options $options * @return array with two elements, the updated $results and the index of the next node. */ public function traverse($results, $key, $cascontext, $options) { $errorfree = true; if ($cascontext->get_errors_key('PRSANS' . $key)) { $results->_errors .= $cascontext->get_errors_key('PRSANS' . $key); $results->add_feedback(' ' . stack_string('prtruntimeerror', array('node' => 'PRSANS' . ($key + 1), 'error' => $cascontext->get_errors_key('PRSANS' . $key)))); $errorfree = false; } if ($cascontext->get_errors_key('PRTANS' . $key)) { $results->_errors .= $cascontext->get_errors_key('PRTANS' . $key); $results->add_feedback(' ' . stack_string('prtruntimeerror', array('node' => 'PRTANS' . ($key + 1), 'error' => $cascontext->get_errors_key('PRTANS' . $key)))); $errorfree = false; } if ($cascontext->get_errors_key('PRATOPT' . $key)) { $results->_errors .= $cascontext->get_errors_key('PRATOPT' . $key); $results->add_feedback(' ' . stack_string('prtruntimeerror', array('node' => 'PRATOPT' . ($key + 1), 'error' => $cascontext->get_errors_key('PRATOPT' . $key)))); $errorfree = false; } if (!$errorfree) { return -1; } $sans = $cascontext->get_value_key('PRSANS' . $key); $tans = $cascontext->get_value_key('PRTANS' . $key); $atopts = $cascontext->get_value_key('PRATOPT' . $key); // If we can't find atopts then they were not processed by the CAS. // They might still be some in the potential response which do not // need to be processed. if (false === $atopts) { $atopts = null; } $nextnode = $this->do_test($sans, $tans, $atopts, $options, $results); return $nextnode; }
public function do_test() { $this->atmark = 1; $anotes = array(); // Note that in casting to an integer we are lucky here. // Non-integer strings get cast to zero, which is invalid anyway.... $atestops = (int) $this->atoption; if (!is_int($atestops) or $atestops <= 0) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => '')); $this->atfeedback .= stack_string('ATNumDecPlaces_OptNotInt', array('opt' => $this->atoption)); $this->atansnote = 'ATNumDecPlaces_STACKERROR_Option.'; $this->atmark = 0; $this->atvalid = false; return null; } $commands = array($this->sanskey, $this->tanskey, (string) $this->atoption); foreach ($commands as $com) { $cs = new stack_cas_casstring($com); if (!$cs->get_valid('t', true, 0)) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => '')); $this->atfeedback .= stack_string('AT_InvalidOptions', array('errors' => $cs->get_errors())); $this->atansnote = 'ATNumDecPlaces_STACKERROR_Option.'; $this->atmark = 0; $this->atvalid = false; return null; } } // Check that the first expression is a floating point number, // with the right number of decimal places. $sans = explode('.', $this->sanskey); if (2 === count($sans)) { if ($atestops != strlen($sans[1])) { $this->atfeedback .= stack_string('ATNumDecPlaces_Wrong_DPs'); $anotes[] = 'ATNumDecPlaces_Wrong_DPs (' . strlen($sans[1]) . ' <> ' . $atestops . ')'; $this->atmark = 0; } else { $anotes[] = 'ATNumDecPlaces_Correct'; } } else { // No '.' found. $this->atfeedback .= stack_string('ATNumDecPlaces_NoDP'); $anotes[] = 'ATNumDecPlaces_NoDP'; $this->atmark = 0; } // Check that the two numbers evaluate to the same value. $cascommands = array(); $cascommands[] = "caschat2:ev({$this->atoption},simp)"; $cascommands[] = "caschat0:ev(float(round(10^caschat2*{$this->sanskey})/10^caschat2),simp)"; $cascommands[] = "caschat1:ev(float(round(10^caschat2*{$this->tanskey})/10^caschat2),simp)"; $cascommands[] = "caschat3:ev(second(ATAlgEquiv(caschat0,caschat1)),simp)"; $cts = array(); foreach ($cascommands as $com) { $cs = new stack_cas_casstring($com); $cs->get_valid('t', true, 0); $cts[] = $cs; } $session = new stack_cas_session($cts, null, 0); $session->instantiate(); if ('' != $session->get_errors_key('caschat0')) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => $session->get_errors_key('caschat0'))); $anotes[] = 'ATNumDecPlaces_STACKERROR_SAns'; $this->atansnote = implode('. ', $anotes) . '.'; $this->atmark = 0; $this->atvalid = false; return null; } if ('' != $session->get_errors_key('caschat1')) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => $session->get_errors_key('caschat1'))); $anotes[] = 'ATNumDecPlaces_STACKERROR_TAns'; $this->atansnote = implode('. ', $anotes) . '.'; $this->atmark = 0; $this->atvalid = false; return null; } if ('' != $session->get_errors_key('caschat2')) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => '')); $this->atfeedback .= stack_string('AT_InvalidOptions', array('errors' => $session->get_errors_key('caschat2'))); $anotes[] = 'ATNumDecPlaces_STACKERROR_Options.'; $this->atansnote = implode('. ', $anotes) . '.'; $this->atmark = 0; $this->atvalid = false; return null; } if ($session->get_value_key('caschat3') == 'true') { // Note, we only want the mark to *stay* at 1. $this->atmark *= 1; $anotes[] = 'ATNumDecPlaces_Equiv'; } else { $this->atmark = 0; $anotes[] = 'ATNumDecPlaces_Not_equiv'; } $this->atansnote = implode('. ', $anotes) . '.'; if ($this->atmark) { return true; } return false; }
public function test_plot_fail() { $cs = array('a:0', 'p:plot(a*x/0,[x,-2,2],[y,-2,2])'); foreach ($cs as $s) { $cs = new stack_cas_casstring($s); $cs->get_valid('t'); $s1[] = $cs; } $at1 = new stack_cas_session($s1, null, 0); $at1->instantiate(); $this->assertEquals('0', $at1->get_value_key('a')); $this->assertEquals('Division by zero.', trim($at1->get_errors_key('p'))); $this->assertFalse(strpos($at1->get_value_key('p'), 'STACK auto-generated plot of 0 with parameters')); }