public function test_validation_error() { $casstring = new stack_cas_casstring('π'); $casstring->get_valid('s'); $this->assertEquals(stack_string('stackCas_forbiddenChar', array('char' => 'π')), $casstring->get_errors()); $this->assertEquals('forbiddenChar', $casstring->get_answernote()); }
public function test_maths_rendering() { if (!stack_maths_output_maths::filter_is_installed()) { $this->markTestSkipped('The OU maths filter is not installed.'); } if (!defined('FILTER_MATHS_TEST_SERVICE_URL_BASE')) { $this->markTestSkipped('To run the OU maths filter output tests, ' . 'you must define FILTER_MATHS_TEST_SERVICE_URL_BASE in config.php.'); } $this->resetAfterTest(); set_config('mathsdisplay', 'maths', 'qtype_stack'); set_config('texservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'tex', 'filter_maths'); set_config('imageservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'imagetex', 'filter_maths'); set_config('englishservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'english', 'filter_maths'); stack_utils::clear_config_cache(); filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED); // Test language string. $this->assertRegExp('~^Your answer needs to be a single fraction of the form <a .*alt="a over b".*</a>\\. $~', stack_string('ATSingleFrac_part')); // Test docs - make sure maths inside <code> is not rendered. $this->assertRegExp('~^<p><code>\\\\\\(x\\^2\\\\\\)</code> gives <a .*alt="x squared".*</a>\\.</p>\\n$~', stack_docs_render_markdown('<code>\\(x^2\\)</code> gives \\(x^2\\).', '')); // Test docs - make sure maths inside <textarea> is not rendered. $this->assertRegExp('~^<p>\\n' . 'Differentiate \\\\\\\\\\[x\\^2 \\+ y\\^2\\\\\\\\\\] with respect to \\\\\\\\\\(x\\\\\\\\\\).</p>\\n$~', stack_docs_render_markdown('<textarea readonly="readonly" rows="3" cols="50">' . "\n" . 'Differentiate \\[x^2 + y^2\\] with respect to \\(x\\).</textarea>', '')); // Test CAS text with inline maths. $this->assertEquals('What is <tex mode="inline">x^2</tex>?', stack_maths::process_display_castext('What is \\(x^2\\)?')); // Test CAS text with display maths. $this->assertEquals('What is <span class="displayequation"><tex mode="display">x^2</tex></span>?', stack_maths::process_display_castext('What is \\[x^2\\]?')); // Test with replacedollars. set_config('replacedollars', '1', 'qtype_stack'); stack_utils::clear_config_cache(); $this->assertEquals('What is <tex mode="inline">x^2</tex> or ' . '<span class="displayequation"><tex mode="display">x^2</tex></span>?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?')); stack_utils::clear_config_cache(); }
protected function extra_validation($contents) { if (strlen($contents[0]) > 1) { return stack_string('singlechargotmorethanone'); } return ''; }
protected function extra_validation($contents) { if (!array_key_exists($contents[0], $this->get_choices())) { return stack_string('booleangotunrecognisedvalue'); } return ''; }
public function add_to_moodleform_testinput(MoodleQuickForm $mform) { $values = $this->get_choices(); if (empty($values)) { $mform->addElement('static', $this->name, stack_string('ddl_empty')); } else { $mform->addElement('select', $this->name, $this->name, $values); } }
public function test_maths_output_mathsjax() { filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED); // MathJax output is the default. $this->assertEquals('Your answer needs to be a single fraction of the form \\( {a}\\over{b} \\). ', stack_string('ATSingleFrac_part')); $this->assertEquals("<p><code>\\(x^2\\)</code> gives \\(x^2\\).</p>\n", stack_docs_render_markdown('`\\(x^2\\)` gives \\(x^2\\).', '')); $this->assertEquals('What is \\(x^2\\)?', stack_maths::process_display_castext('What is \\(x^2\\)?')); $this->resetAfterTest(); set_config('replacedollars', '1', 'qtype_stack'); stack_utils::clear_config_cache(); $this->assertEquals('What is \\(x^2\\) or \\[x^2\\]?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?')); stack_utils::clear_config_cache(); }
/** * Translates a string taken as output from Maxima. * * This function takes a variable number of arguments, the first of which is assumed to be the identifier * of the string to be translated. */ function stack_trans() { $nargs = func_num_args(); if ($nargs > 0) { $arglist = func_get_args(); $identifier = func_get_arg(0); $a = array(); if ($nargs > 1) { for ($i = 1; $i < $nargs; $i++) { $index = $i - 1; $a["m{$index}"] = func_get_arg($i); } } $return = stack_string($identifier, $a); echo $return; } }
private function validate() { if (empty($this->raw) or '' == trim($this->raw)) { $this->valid = true; return true; } // CAS keyval may not contain @ or $. if (strpos($this->raw, '@') !== false || strpos($this->raw, '$') !== false) { $this->errors = stack_string('illegalcaschars'); $this->valid = false; return false; } // Subtle one: must protect things inside strings before we explode. $str = $this->raw; $strings = stack_utils::all_substring_strings($str); foreach ($strings as $key => $string) { $str = str_replace('"' . $string . '"', '[STR:' . $key . ']', $str); } $str = str_replace("\n", ';', $str); $str = stack_utils::remove_comments($str); $str = str_replace(';', "\n", $str); $kvarray = explode("\n", $str); foreach ($strings as $key => $string) { foreach ($kvarray as $kkey => $kstr) { $kvarray[$kkey] = str_replace('[STR:' . $key . ']', '"' . $string . '"', $kstr); } } // 23/4/12 - significant changes to the way keyvals are interpreted. Use Maxima assignmentsm i.e. x:2. $errors = ''; $valid = true; $vars = array(); foreach ($kvarray as $kvs) { $kvs = trim($kvs); if ('' != $kvs) { $cs = new stack_cas_casstring($kvs); $cs->get_valid($this->security, $this->syntax, $this->insertstars); $vars[] = $cs; } } $this->session->add_vars($vars); $this->valid = $this->session->get_valid(); $this->errors = $this->session->get_errors(); }
public function do_test() { if ($this->atoption == null) { $this->aterror = 'TEST_FAILED'; $this->atfeedback = stack_string('TEST_FAILED', array('errors' => '')); $this->atansnote = 'ATRegEx_STACKERROR_Option.'; $this->atmark = 0; $this->atvalid = false; return null; } else { $this->atvalid = true; if (preg_match($this->atoption, $this->sanskey, $pattern)) { $this->atmark = 1; $this->atansnote = ' Pattern matched: ' . $pattern[0] . '.'; return true; } else { $this->atmark = 0; return false; } } }
public function test_tex_rendering() { $this->resetAfterTest(); set_config('mathsdisplay', 'tex', 'qtype_stack'); stack_utils::clear_config_cache(); filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED); // Test language string. // The <span class="MathJax_Preview"> bit is something that got added in // Moodle 2.8, so match it optionally. $this->assertRegExp('~^Your answer needs to be a single fraction of the form ' . '(<span class="MathJax_Preview">)?<a .*alt=" \\{a\\}\\\\over\\{b\\} ".*</(a|script)> \\. ~', stack_string('ATSingleFrac_part')); // Test docs - make sure maths inside <code> is not rendered. $this->assertRegExp('~^<p><code>\\\\\\(x\\^2\\\\\\)</code> gives (<span class="MathJax_Preview">)?<a .*alt="x\\^2".*</(a|script)> \\.</p>\\n$~', stack_docs_render_markdown('<code>\\(x^2\\)</code> gives \\(x^2\\).', '')); // Test docs - make sure maths inside <textarea> is not rendered. $this->assertRegExp('~^<p>\\n' . 'Differentiate \\\\\\\\\\[x\\^2 \\+ y\\^2\\\\\\\\\\] with respect to \\\\\\\\\\(x\\\\\\\\\\).</p>\\n$~', stack_docs_render_markdown('<textarea readonly="readonly" rows="3" cols="50">' . "\n" . 'Differentiate \\[x^2 + y^2\\] with respect to \\(x\\).</textarea>', '')); // Test CAS text with inline maths. $this->assertEquals('What is \\[x^2\\]?', stack_maths::process_display_castext('What is \\(x^2\\)?')); // Test CAS text with display maths. $this->assertEquals('What is <span class="displayequation">\\[\\displaystyle x^2\\]</span>?', stack_maths::process_display_castext('What is \\[x^2\\]?')); // Test with replacedollars. set_config('replacedollars', '1', 'qtype_stack'); stack_utils::clear_config_cache(); $this->assertEquals('What is \\[x^2\\] or <span class="displayequation">\\[\\displaystyle x^2\\]</span>?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?')); stack_utils::clear_config_cache(); }
protected function definition() { $mform = $this->_form; $question = $this->_customdata['question']; // Inputs. $mform->addElement('header', 'inputsheader', stack_string('testinputs')); foreach ($question->inputs as $inputname => $input) { // We do not require these to be filled in, (or contain valid input), as the teacher may want to test such cases. $input->add_to_moodleform_testinput($mform); } $mform->addElement('submit', 'complete', stack_string('completetestcase')); $mform->registerNoSubmitButton('complete'); // Expected outcome. $mform->addElement('header', 'prtsheader', stack_string('expectedoutcomes')); foreach ($question->prts as $prtname => $prt) { $elements = array($mform->createElement('text', $prtname . 'score', stack_string('score'), array('size' => 2)), $mform->createElement('text', $prtname . 'penalty', stack_string('penalty'), array('size' => 2)), $mform->createElement('select', $prtname . 'answernote', stack_string('answernote'), $prt->get_all_answer_notes())); $mform->addGroup($elements, $prtname . 'group', $prtname, ' ', false); $mform->setType($prtname . 'score', PARAM_RAW); $mform->setType($prtname . 'penalty', PARAM_RAW); $mform->setType($prtname . 'answernote', PARAM_RAW); } // Submit buttons. $this->add_action_buttons(true, $this->_customdata['submitlabel']); }
public function test_test0_no_validation_required() { // Account for the changes in Moodle 2.6. if (question_cbm::adjust_fraction(1, question_cbm::HIGH) > 2) { // Moodle 2.6+. $outof = 1; } else { // Moodle 2.5-. $outof = 3; } // Create a stack question - we use test0, then replace the input with // a dropdown, to get a question that does not require validation. $q = test_question_maker::make_question('stack', 'test0'); $q->inputs['ans1'] = stack_input_factory::make('dropdown', 'ans1', '2', array('ddl_values' => '1,2')); $this->start_attempt_at_question($q, 'deferredcbm', $outof); // Check the right behaviour is used. $this->assertEquals('deferredcbm', $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); // Check the initial state. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->render(); $this->check_output_does_not_contain_input_validation(); $this->check_output_does_not_contain_prt_feedback(); $this->check_output_does_not_contain_stray_placeholders(); $this->check_current_output($this->get_contains_select_expectation('ans1', array('' => stack_string('notanswered'), '1' => '1', '2' => '2'), null, true), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_num_parts_correct(), $this->get_no_hint_visible_expectation()); // Save a correct response, medium certainty. $this->process_submission(array('ans1' => '2', '-certainty' => 2)); $this->check_current_state(question_state::$complete); $this->check_current_mark(null); $this->render(); $this->check_output_does_not_contain_input_validation(); $this->check_output_does_not_contain_prt_feedback(); $this->check_output_does_not_contain_stray_placeholders(); $this->check_current_output($this->get_contains_select_expectation('ans1', array('' => stack_string('notanswered'), '1' => '1', '2' => '2'), '2', true), $this->get_does_not_contain_feedback_expectation(), $this->get_does_not_contain_num_parts_correct(), $this->get_no_hint_visible_expectation()); // Submit all and finish. $this->quba->finish_all_questions(); $this->check_current_state(question_state::$gradedright); $this->check_current_mark(2); $this->render(); $this->check_output_does_not_contain_input_validation(); $this->check_output_contains_prt_feedback('firsttree'); $this->check_output_does_not_contain_stray_placeholders(); $this->check_current_output($this->get_contains_select_expectation('ans1', array('' => stack_string('notanswered'), '1' => '1', '2' => '2'), '2', false), $this->get_does_not_contain_num_parts_correct(), $this->get_no_hint_visible_expectation()); }
/** * Check a form field to ensure it does not contain any placeholders of given types. * @param string $fieldname the name of this field. Used in the error messages. * @param value $value the value to check. * @param array $placeholders types to check for. By default 'input', 'validation' and 'feedback'. * @return array of problems (so an empty array means all is well). */ protected function check_no_placeholders($fieldname, $value, $placeholders = array('input', 'validation', 'feedback')) { $problems = array(); foreach ($placeholders as $placeholder) { if (stack_utils::extract_placeholders($value, 'input')) { $problems[] = stack_string('fieldshouldnotcontainplaceholder', array('field' => $fieldname, 'type' => $placeholder)); } } return $problems; }
/** * Deals with Maxima errors. Enables some translation. * * @param string $errstr a Maxima error string * @return string */ protected function tidy_error($errstr) { // This case arises when we use a numerical text for algebraic equivalence. if (strpos($errstr, 'STACK: ignore previous error.') !== false) { return ''; } if (strpos($errstr, '0 to a negative exponent') !== false) { $errstr = stack_string('Maxima_DivisionZero'); } return $errstr; }
// // You should have received a copy of the GNU General Public License // along with Stack. If not, see <http://www.gnu.org/licenses/>. /** * This script provdies an index for running the question tests in bulk. * * @copyright 2013 the Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once __DIR__ . '/../../../config.php'; require_once $CFG->libdir . '/questionlib.php'; require_once __DIR__ . '/locallib.php'; require_once __DIR__ . '/stack/utils.class.php'; // Login and check permissions. $context = context_system::instance(); require_login(); require_capability('qtype/stack:usediagnostictools', $context); $PAGE->set_url('/question/type/stack/bulktestindex.php'); $PAGE->set_context($context); $PAGE->set_title(stack_string('bulktestindextitle')); // Load the necessary data. $counts = $DB->get_records_sql_menu("\n SELECT ctx.id, COUNT(q.id) AS numstackquestions\n FROM {context} ctx\n JOIN {question_categories} qc ON qc.contextid = ctx.id\n JOIN {question} q ON q.category = qc.id\n WHERE q.qtype = 'stack'\n GROUP BY ctx.id, ctx.path\n ORDER BY ctx.path\n "); // Display. echo $OUTPUT->header(); echo $OUTPUT->heading(stack_string('replacedollarsindex')); echo html_writer::start_tag('ul'); foreach ($counts as $contextid => $numstackquestions) { echo html_writer::tag('li', html_writer::link(new moodle_url('/question/type/stack/bulktest.php', array('contextid' => $contextid)), context::instance_by_id($contextid)->get_context_name(true, true) . ' (' . $numstackquestions . ')')); } echo html_writer::end_tag('ul'); echo $OUTPUT->footer();
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once __DIR__ . '/../../../config.php'; require_once $CFG->libdir . '/questionlib.php'; require_once __DIR__ . '/locallib.php'; require_once __DIR__ . '/stack/utils.class.php'; require_once __DIR__ . '/stack/bulktester.class.php'; // Get the parameters from the URL. $contextid = required_param('contextid', PARAM_INT); // Login and check permissions. $context = context::instance_by_id($contextid); require_login(); require_capability('qtype/stack:usediagnostictools', $context); $PAGE->set_url('/question/type/stack/bulktest.php', array('contextid' => $context->id)); $PAGE->set_context($context); $title = stack_string('bulktesttitle', $context->get_context_name()); $PAGE->set_title($title); if ($context->contextlevel == CONTEXT_MODULE) { // Calling $PAGE->set_context should be enough, but it seems that it is not. // Therefore, we get the right $cm and $course, and set things up ourselves. $cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST); $PAGE->set_cm($cm, $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST)); } // Create the helper class. $bulktester = new stack_bulk_tester(); // Release the session, so the user can do other things while this runs. \core\session\manager::write_close(); // Display. echo $OUTPUT->header(); echo $OUTPUT->heading($title); // Run the tests.
/** * Validates the options, when needed. * * @return (bool, errors) * @access public */ public function validate_atoptions($opt) { $atestops = (int) $opt; if (!is_int($atestops) or $atestops <= 0) { return array(false, stack_string('ATNumDecPlaces_OptNotInt', array('opt' => $opt))); } return array(true, ''); }
} else { $class = 'fail'; $passedcol = stack_string('testsuitefail'); } $display = ''; if ('' != $casdisplay) { $display = '\\(' . $casdisplay . '\\)'; } $row = array('passed' => $passedcol, 'studentanswer' => s($test->rawstring), 'phpvalid' => s($phpvalid), 'phpcasstring' => s($phpcasstring), 'answernote' => $answernote, 'error' => $error, 'casvalid' => s($casvalid), 'casvalue' => $casvalue, 'casdisplay' => format_text(stack_maths::process_lang_string(s($display))) . html_writer::tag('pre', s($casdisplay)), 'caserrors' => $caserrors); $table->add_data_keyed($row, $class); flush(); } $table->finish_output(); // Overall summary. $took = microtime(true) - $start; $rtook = round($took, 5); $pertest = round($took / $notests, 5); echo '<p>' . stack_string('testsuitenotests', array('no' => $notests)); echo '<br/>' . stack_string('testsuiteteststook', array('time' => $rtook)); echo '<br/>' . stack_string('testsuiteteststookeach', array('time' => $pertest)); echo '</p>'; $config = get_config('qtype_stack'); echo html_writer::tag('p', stack_string('healthcheckcache_' . $config->casresultscache)); // Overall summary. if ($allpassed) { echo $OUTPUT->heading(stack_string('stackInstall_testsuite_pass'), 2, 'pass'); } else { echo $OUTPUT->heading(stack_string('stackInstall_testsuite_fail'), 2, 'fail'); } // Finish output. echo $OUTPUT->footer();
* * @package qtype_stack * @copyright 2013 the Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once __DIR__ . '/../../../config.php'; require_once $CFG->libdir . '/questionlib.php'; require_once __DIR__ . '/locallib.php'; require_once __DIR__ . '/stack/utils.class.php'; require_once __DIR__ . '/stack/bulktester.class.php'; // Login and check permissions. $context = context_system::instance(); require_login(); require_capability('qtype/stack:usediagnostictools', $context); $PAGE->set_url('/question/type/stack/bulktestindex.php'); $PAGE->set_context($context); $PAGE->set_title(stack_string('bulktestindextitle')); // Create the helper class. $bulktester = new stack_bulk_tester(); // Display. echo $OUTPUT->header(); echo $OUTPUT->heading(stack_string('replacedollarsindex')); echo html_writer::start_tag('ul'); foreach ($bulktester->get_stack_questions_by_context() as $contextid => $numstackquestions) { echo html_writer::tag('li', html_writer::link(new moodle_url('/question/type/stack/bulktest.php', array('contextid' => $contextid)), context::instance_by_id($contextid)->get_context_name(true, true) . ' (' . $numstackquestions . ')')); } echo html_writer::end_tag('ul'); if (has_capability('moodle/site:config', context_system::instance())) { echo html_writer::tag('p', html_writer::link(new moodle_url('/question/type/stack/bulktestall.php'), stack_string('bulktestrun'))); } echo $OUTPUT->footer();
/** * Generate the HTML that gives the results of validating the student's input. * @param stack_input_state $state represents the results of the validation. * @param string $fieldname the field name to use in the HTML for this input. * @return string HTML for the validation results for this input. */ public function render_validation(stack_input_state $state, $fieldname) { if (self::BLANK == $state->status) { return ''; } if ($this->get_parameter('showValidation', 1) == 0 && self::INVALID != $state->status) { return ''; } $feedback = ''; $feedback .= html_writer::tag('p', stack_string('studentValidation_yourLastAnswer', $state->contentsdisplayed)); if ($this->requires_validation() && '' !== $state->contents) { $feedback .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $fieldname . '_val', 'value' => $this->contents_to_maxima($state->contents))); } if (self::INVALID == $state->status) { $feedback .= html_writer::tag('p', stack_string('studentValidation_invalidAnswer')); } if ($state->errors) { $feedback .= html_writer::tag('p', $state->errors, array('class' => 'stack_errors')); } if ($this->get_parameter('showValidation', 1) == 1 && !($state->lvars === '' or $state->lvars === '[]')) { $feedback .= html_writer::tag('p', stack_string('studentValidation_listofvariables', $state->lvars)); } return $feedback; }
public function test_fact_sheets() { $cs2 = new stack_cas_session(array(), null, 0); $at1 = new stack_cas_text("[[facts:calc_diff_linearity_rule]]", $cs2, 0); $output = stack_maths::process_display_castext($at1->get_display_castext()); $this->assertContains(stack_string('calc_diff_linearity_rule_name'), $output); $this->assertContains(stack_string('calc_diff_linearity_rule_fact'), $output); }
private function display_question_information($question) { global $OUTPUT; $opts = $question->options; echo $OUTPUT->heading($question->name, 3); // Display the question variables. echo $OUTPUT->heading(stack_string('questionvariables'), 3); echo html_writer::start_tag('div', array('class' => 'questionvariables')); echo html_writer::tag('pre', htmlspecialchars($opts->questionvariables)); echo html_writer::end_tag('div'); echo $OUTPUT->heading(stack_string('questiontext'), 3); echo html_writer::tag('div', html_writer::tag('div', stack_ouput_castext($question->questiontext), array('class' => 'outcome generalfeedback')), array('class' => 'que')); echo $OUTPUT->heading(stack_string('generalfeedback'), 3); echo html_writer::tag('div', html_writer::tag('div', stack_ouput_castext($question->generalfeedback), array('class' => 'outcome generalfeedback')), array('class' => 'que')); echo $OUTPUT->heading(stack_string('questionnote'), 3); echo html_writer::tag('div', html_writer::tag('div', stack_ouput_castext($opts->questionnote), array('class' => 'outcome generalfeedback')), array('class' => 'que')); echo $OUTPUT->heading(get_string('pluginname', 'quiz_stack'), 3); }
public static function stackmaxima_auto_maxima_optimise($genuinedebug) { global $CFG; self::ensure_config_loaded(); $imagename = stack_utils::convert_slash_paths($CFG->dataroot . '/stack/maxima_opt_auto'); $lisp = '1'; // Try to guess the lisp version. if (!(false === strpos($genuinedebug, 'GNU Common Lisp (GCL)'))) { $lisp = 'GCL'; } if (!(false === strpos($genuinedebug, 'Lisp SBCL'))) { $lisp = 'SBCL'; } if (!(false === strpos($genuinedebug, 'Lisp CLISP'))) { $lisp = 'CLISP'; } switch ($lisp) { case 'GCL': $maximacommand = ':lisp (si::save-system "' . $imagename . '")' . "\n"; $maximacommand .= 'quit();' . "\n"; $commandline = stack_utils::convert_slash_paths($imagename . ' -eval \'(cl-user::run)\''); break; case 'SBCL': $maximacommand = ':lisp (sb-ext:save-lisp-and-die "' . $imagename . '" :toplevel #\'run :executable t)' . "\n"; $commandline = stack_utils::convert_slash_paths($imagename); break; case 'CLISP': $imagename .= '.mem'; $maximacommand = ':lisp (ext:saveinitmem "' . $imagename . '" :init-function #\'user::run)' . "\n"; $maximacommand .= 'quit();' . "\n"; $lisprun = shell_exec('locate lisp.run'); if (trim($lisprun) == '') { $success = false; $message = stack_string('healthautomaxopt_nolisprun'); return array($message, '', $success); } $lisprun = explode("\n", $lisprun); $commandline = $lisprun[0] . ' -q -M ' . stack_utils::convert_slash_paths($imagename); break; default: $success = false; $message = stack_string('healthautomaxopt_nolisp'); return array($message, '', $success); } // Really make sure there is no cache. list($results, $debug) = self::stackmaxima_nocache_call($maximacommand); // Question: should we at this stage try to use the optimised image we have created? $success = true; // Add the timeout command to the message. $commandline = 'timeout --kill-after=10s 10s ' . $commandline; $message = stack_string('healthautomaxopt_ok', array('command' => $commandline)); if (!file_exists($imagename)) { $success = false; $message = stack_string('healthautomaxopt_notok'); } return array($message, $debug, $success); }
/** * Generate an error page when missing docs are referred to. * @param string $links menu of links to show. * @return string HTML page body. */ function stack_docs_no_found($links) { $body = ''; $body .= html_writer::tag('h1', stack_string('stackDoc_404')); $body .= html_writer::tag('p', stack_string('stackDoc_404message')); $body .= $links; return $body; }
function output_cas_text($title, $intro, $castext) { global $OUTPUT; echo $OUTPUT->heading($title, 3); echo html_writer::tag('p', $intro); echo html_writer::tag('pre', s($castext)); $ct = new stack_cas_text($castext, null, 0, 't'); echo html_writer::tag('p', format_text(stack_ouput_castext($ct->get_display_castext()))); echo output_debug(stack_string('errors'), $ct->get_errors()); echo output_debug(stack_string('debuginfo'), $ct->get_debuginfo()); }
$variantdeployed = true; $failedattempts++; } } if (!$variantdeployed) { // Load the list of test cases. $testscases = question_bank::get_qtype('stack')->load_question_tests($question->id); // Exectue the tests. $testresults = array(); $allpassed = true; foreach ($testscases as $key => $testcase) { $testresults[$key] = $testcase->test_question($quba, $question, $seed); if (!$testresults[$key]->passed()) { $nexturl->param('seed', $seed); $nexturl->param('deployfeedback', stack_string('deploymanysuccess', array('no' => $numberdeployed))); $nexturl->param('deployfeedbackerr', stack_string('stackInstall_testsuite_fail')); redirect($nexturl); } } // Actually deploy the question. $question->deploy_variant($seed); $numberdeployed++; } } $nexturl->param('deployfeedback', stack_string('deploymanysuccess', array('no' => $numberdeployed))); $nexturl->param('seed', $seed); if ($failedattempts >= $maxfailedattempts) { $nexturl->param('deployfeedbackerr', stack_string('deploymanynonew')); } redirect($nexturl); }
/** * * * @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; } }
public function instantiate() { if (null === $this->valid) { $this->validate(); } if (!$this->valid) { return false; } // Lazy instantiation - only do this once... // Empty session. Nothing to do. if ($this->instantiated || null === $this->session) { return true; } $connection = stack_connection_helper::make(); $results = $connection->compute($this->construct_maxima_command()); $this->debuginfo = $connection->get_debuginfo(); // Now put the information back into the correct slots. $session = $this->session; $newsession = array(); $newerrors = ''; $allfail = true; $i = 0; // We loop over each entry in the session, not over the result. // This way we can add an error for missing values. foreach ($session as $cs) { $gotvalue = false; if ('' == $cs->get_key()) { $key = 'dumvar' . $i; } else { $key = $cs->get_key(); } if (array_key_exists($i, $results)) { $allfail = false; // We at least got one result back from the CAS! $result = $results["{$i}"]; // GOCHA! Results have string represenations of numbers, not int.... if ('' != $result['error'] and false === strstr($result['error'], 'clipped')) { $cs->add_errors($result['error']); $cs->decode_maxima_errors($result['error']); $newerrors .= stack_maxima_format_casstring($cs->get_raw_casstring()); $newerrors .= ' ' . stack_string("stackCas_CASErrorCaused") . ' ' . $result['error'] . ' '; } if (array_key_exists('value', $result)) { $val = str_replace('QMCHAR', '?', $result['value']); $cs->set_value($val); $gotvalue = true; } else { $cs->add_errors(stack_string("stackCas_failedReturnOne")); } if (array_key_exists('display', $result)) { // Need to add this in here also because strings may contain question mark characters. $disp = str_replace('QMCHAR', '?', $result['display']); $cs->set_display($disp); } if (array_key_exists('valid', $result)) { $cs->set_valid($result['valid']); } if (array_key_exists('answernote', $result)) { $cs->set_answernote($result['answernote']); } if (array_key_exists('feedback', $result)) { $cs->set_feedback($result['feedback']); } } else { if (!$gotvalue) { $errstr = stack_string("stackCas_failedReturn") . ' ' . stack_maxima_format_casstring($cs->get_raw_casstring()); $cs->add_errors($errstr); $cs->set_answernote('CASFailedReturn'); $newerrors .= $errstr; } } $newsession[] = $cs; $i++; } $this->session = $newsession; if ('' != $newerrors) { $this->errors .= '<span class="error">' . stack_string('stackCas_CASError') . '</span>' . $newerrors; } if ($allfail) { $this->errors = '<span class="error">' . stack_string('stackCas_allFailed') . '</span>'; } $this->instantiated = true; }
/** * Check for strings within the casstring. This is only used in the "fobidden words" option. * @return bool|string true if an element of array is found in the casstring. */ public function check_external_forbidden_words_literal($keywords) { if (null === $this->valid) { $this->validate(); } // Deal with escaped commas. $keywords = str_replace('\\,', 'COMMA_TAG', $keywords); $keywords = explode(',', $keywords); // Replace lists of keywords with their actual values. $kws = array(); foreach ($keywords as $val) { $kw = trim(strtolower($val)); if (array_key_exists($kw, self::$keywordlists)) { $kws = array_merge($kws, self::$keywordlists[$kw]); } else { if ('COMMA_TAG' === $val) { $kws[] = ','; } else { $kws[] = trim($val); // This test is case sensitive, but ignores surrounding whitespace. } } } $found = false; foreach ($kws as $key) { if (!(false === strpos($this->rawcasstring, $key))) { $found = true; $this->valid = false; $this->add_error(stack_string('stackCas_forbiddenWord', array('forbid' => stack_maxima_format_casstring($key)))); } } return $found; }
protected function expected_choices() { return array('' => stack_string('notanswered'), 'x+1' => 'x+1', 'x+2' => 'x+2', 'x+3' => 'x+3'); }