public function test_modinput_tokenizer_incomplete_row()
 {
     $in = '1,';
     $out = array('1', '');
     $el = stack_input_factory::make('matrix', 'ans1', 'M');
     $this->assertEquals($out, $el->modinput_tokenizer($in));
 }
 public function test_validate_student_response_error()
 {
     $options = new stack_options();
     $el = stack_input_factory::make('boolean', 'sans1', 'true');
     $state = $el->validate_student_response(array('sans1' => 'frog'), $options, 'true', null);
     $this->assertEquals(stack_input::INVALID, $state->status);
 }
 public function load_choices()
 {
     global $CFG;
     require_once $CFG->dirroot . '/question/type/stack/stack/input/factory.class.php';
     if (is_array($this->choices)) {
         return true;
     }
     $this->choices = stack_input_factory::get_available_type_choices();
     return true;
 }
 protected function definition_inner($mform)
 {
     // Load the configuration.
     $this->stackconfig = stack_utils::get_config();
     // Prepare input types.
     $this->typechoices = stack_input_factory::get_available_type_choices();
     // Prepare answer test types.
     $answertests = stack_ans_test_controller::get_available_ans_tests();
     // Algebraic Equivalence should be the default test, and first on the list.
     // This does not come first in the alphabet of all languages.
     $default = 'AlgEquiv';
     $defaultstr = stack_string($answertests[$default]);
     unset($answertests[$default]);
     $this->answertestchoices = array();
     foreach ($answertests as $test => $string) {
         $this->answertestchoices[$test] = stack_string($string);
     }
     stack_utils::sort_array($this->answertestchoices);
     $this->answertestchoices = array_merge(array($default => $defaultstr), $this->answertestchoices);
     // Prepare score mode choices.
     $this->scoremodechoices = array('=' => '=', '+' => '+', '-' => '-');
     $inputnames = $this->get_input_names_from_question_text();
     $prtnames = $this->get_prt_names_from_question();
     // Note that for the editor elements, we are using
     // $mform->getElement('prtincorrect')->setValue(...);
     // instead of setDefault, because setDefault does not work for editors.
     $mform->addHelpButton('questiontext', 'questiontext', 'qtype_stack');
     $mform->addRule('questiontext', stack_string('questiontextnonempty'), 'required', '', 'client');
     $qvars = $mform->createElement('textarea', 'questionvariables', stack_string('questionvariables'), array('rows' => 5, 'cols' => 80));
     $mform->insertElementBefore($qvars, 'questiontext');
     $mform->addHelpButton('questionvariables', 'questionvariables', 'qtype_stack');
     $seed = $mform->createElement('text', 'variantsselectionseed', stack_string('variantsselectionseed'), array('size' => 50));
     $mform->insertElementBefore($seed, 'questiontext');
     $mform->setType('variantsselectionseed', PARAM_RAW);
     $mform->addHelpButton('variantsselectionseed', 'variantsselectionseed', 'qtype_stack');
     $sf = $mform->createElement('editor', 'specificfeedback', get_string('specificfeedback', 'question'), array('rows' => 10), $this->editoroptions);
     $mform->insertElementBefore($sf, 'generalfeedback');
     $mform->getElement('specificfeedback')->setValue(array('text' => self::DEFAULT_SPECIFIC_FEEDBACK));
     $mform->addHelpButton('specificfeedback', 'specificfeedback', 'qtype_stack');
     $mform->addHelpButton('generalfeedback', 'generalfeedback', 'qtype_stack');
     $mform->addElement('textarea', 'questionnote', stack_string('questionnote'), array('rows' => 2, 'cols' => 80));
     $mform->addHelpButton('questionnote', 'questionnote', 'qtype_stack');
     $mform->addElement('submit', 'verify', stack_string('verifyquestionandupdate'));
     $mform->registerNoSubmitButton('verify');
     // Inputs.
     foreach ($inputnames as $inputname => $counts) {
         $this->definition_input($inputname, $mform, $counts);
     }
     // PRTs.
     foreach ($prtnames as $prtname => $count) {
         $this->definition_prt($prtname, $mform, $count);
     }
     // Options.
     $mform->addElement('header', 'optionsheader', stack_string('options'));
     $mform->addElement('selectyesno', 'questionsimplify', stack_string('questionsimplify'));
     $mform->setDefault('questionsimplify', $this->stackconfig->questionsimplify);
     $mform->addHelpButton('questionsimplify', 'autosimplify', 'qtype_stack');
     $mform->addElement('selectyesno', 'assumepositive', stack_string('assumepositive'));
     $mform->setDefault('assumepositive', $this->stackconfig->assumepositive);
     $mform->addHelpButton('assumepositive', 'assumepositive', 'qtype_stack');
     $mform->addElement('editor', 'prtcorrect', stack_string('prtcorrectfeedback'), array('rows' => 1), $this->editoroptions);
     $mform->getElement('prtcorrect')->setValue(array('text' => $this->stackconfig->prtcorrect));
     $mform->addElement('editor', 'prtpartiallycorrect', stack_string('prtpartiallycorrectfeedback'), array('rows' => 1), $this->editoroptions);
     $mform->getElement('prtpartiallycorrect')->setValue(array('text' => $this->stackconfig->prtpartiallycorrect));
     $mform->addElement('editor', 'prtincorrect', stack_string('prtincorrectfeedback'), array('rows' => 1), $this->editoroptions);
     $mform->getElement('prtincorrect')->setValue(array('text' => $this->stackconfig->prtincorrect));
     $mform->addElement('select', 'multiplicationsign', stack_string('multiplicationsign'), stack_options::get_multiplication_sign_options());
     $mform->setDefault('multiplicationsign', $this->stackconfig->multiplicationsign);
     $mform->addHelpButton('multiplicationsign', 'multiplicationsign', 'qtype_stack');
     $mform->addElement('selectyesno', 'sqrtsign', stack_string('sqrtsign'));
     $mform->setDefault('sqrtsign', $this->stackconfig->sqrtsign);
     $mform->addHelpButton('sqrtsign', 'sqrtsign', 'qtype_stack');
     $mform->addElement('select', 'complexno', stack_string('complexno'), stack_options::get_complex_no_options());
     $mform->setDefault('complexno', $this->stackconfig->complexno);
     $mform->addHelpButton('complexno', 'complexno', 'qtype_stack');
     $mform->addElement('select', 'inversetrig', stack_string('inversetrig'), stack_options::get_inverse_trig_options());
     $mform->setDefault('inversetrig', $this->stackconfig->inversetrig);
     $mform->addHelpButton('inversetrig', 'inversetrig', 'qtype_stack');
     $mform->addElement('select', 'matrixparens', stack_string('matrixparens'), stack_options::get_matrix_parens_options());
     $mform->setDefault('matrixparens', $this->stackconfig->matrixparens);
     $mform->addHelpButton('matrixparens', 'matrixparens', 'qtype_stack');
     // Hints.
     $this->add_interactive_settings();
     // Replace standard penalty input at the bottom with the one we want.
     $mform->removeElement('multitriesheader');
     $mform->removeElement('penalty');
     $pen = $mform->createElement('text', 'penalty', stack_string('penalty'), array('size' => 5));
     $mform->insertElementBefore($pen, 'generalfeedback');
     $mform->setType('penalty', PARAM_FLOAT);
     $mform->addHelpButton('penalty', 'penalty', 'qtype_stack');
     $mform->setDefault('penalty', 0.1);
     $mform->addRule('penalty', null, 'required', null, 'client');
 }
 protected function initialise_question_instance(question_definition $question, $questiondata)
 {
     parent::initialise_question_instance($question, $questiondata);
     $question->questionvariables = $questiondata->options->questionvariables;
     $question->questionnote = $questiondata->options->questionnote;
     $question->specificfeedback = $questiondata->options->specificfeedback;
     $question->specificfeedbackformat = $questiondata->options->specificfeedbackformat;
     $question->prtcorrect = $questiondata->options->prtcorrect;
     $question->prtcorrectformat = $questiondata->options->prtcorrectformat;
     $question->prtpartiallycorrect = $questiondata->options->prtpartiallycorrect;
     $question->prtpartiallycorrectformat = $questiondata->options->prtpartiallycorrectformat;
     $question->prtincorrect = $questiondata->options->prtincorrect;
     $question->prtincorrectformat = $questiondata->options->prtincorrectformat;
     $question->variantsselectionseed = $questiondata->options->variantsselectionseed;
     $question->options = new stack_options();
     $question->options->set_option('multiplicationsign', $questiondata->options->multiplicationsign);
     $question->options->set_option('complexno', $questiondata->options->complexno);
     $question->options->set_option('inversetrig', $questiondata->options->inversetrig);
     $question->options->set_option('matrixparens', $questiondata->options->matrixparens);
     $question->options->set_option('sqrtsign', (bool) $questiondata->options->sqrtsign);
     $question->options->set_option('simplify', (bool) $questiondata->options->questionsimplify);
     $question->options->set_option('assumepos', (bool) $questiondata->options->assumepositive);
     $requiredparams = stack_input_factory::get_parameters_used();
     foreach ($questiondata->inputs as $name => $inputdata) {
         $allparameters = array('boxWidth' => $inputdata->boxsize, 'strictSyntax' => (bool) $inputdata->strictsyntax, 'insertStars' => (int) $inputdata->insertstars, 'syntaxHint' => $inputdata->syntaxhint, 'forbidWords' => $inputdata->forbidwords, 'allowWords' => $inputdata->allowwords, 'forbidFloats' => (bool) $inputdata->forbidfloat, 'lowestTerms' => (bool) $inputdata->requirelowestterms, 'sameType' => (bool) $inputdata->checkanswertype, 'mustVerify' => (bool) $inputdata->mustverify, 'showValidation' => $inputdata->showvalidation);
         $parameters = array();
         foreach ($requiredparams[$inputdata->type] as $paramname) {
             if ($paramname == 'inputType') {
                 continue;
             }
             $parameters[$paramname] = $allparameters[$paramname];
         }
         // TODO: Do something with $inputdata->options here.
         $question->inputs[$name] = stack_input_factory::make($inputdata->type, $inputdata->name, $inputdata->tans, $parameters);
     }
     $totalvalue = 0;
     foreach ($questiondata->prts as $name => $prtdata) {
         $totalvalue += $prtdata->value;
     }
     if ($questiondata->prts && $totalvalue < 1.0E-7) {
         throw new coding_exception('There is an error authoring your question. ' . 'The $totalvalue, the marks available for the question, must be positive in question ' . $question->name);
     }
     foreach ($questiondata->prts as $name => $prtdata) {
         $nodes = array();
         foreach ($prtdata->nodes as $nodedata) {
             $sans = new stack_cas_casstring($nodedata->sans);
             $sans->get_valid('t');
             $tans = new stack_cas_casstring($nodedata->tans);
             $tans->get_valid('t');
             if (is_null($nodedata->falsepenalty) || $nodedata->falsepenalty === '') {
                 $falsepenalty = $questiondata->penalty;
             } else {
                 $falsepenalty = $nodedata->falsepenalty;
             }
             if (is_null($nodedata->truepenalty) || $nodedata->truepenalty === '') {
                 $truepenalty = $questiondata->penalty;
             } else {
                 $truepenalty = $nodedata->truepenalty;
             }
             $node = new stack_potentialresponse_node($sans, $tans, $nodedata->answertest, $nodedata->testoptions, (bool) $nodedata->quiet, '', $nodedata->id);
             $node->add_branch(0, $nodedata->falsescoremode, $nodedata->falsescore, $falsepenalty, $nodedata->falsenextnode, $nodedata->falsefeedback, $nodedata->falsefeedbackformat, $nodedata->falseanswernote);
             $node->add_branch(1, $nodedata->truescoremode, $nodedata->truescore, $truepenalty, $nodedata->truenextnode, $nodedata->truefeedback, $nodedata->truefeedbackformat, $nodedata->trueanswernote);
             $nodes[$nodedata->nodename] = $node;
         }
         // TODO $feedbackvariables, and $sans, $tans, should probably still be strings
         // here, and should be converted to CAS stuff later, only if needed.
         if ($prtdata->feedbackvariables) {
             $feedbackvariables = new stack_cas_keyval($prtdata->feedbackvariables, null, null, 't');
             $feedbackvariables = $feedbackvariables->get_session();
         } else {
             $feedbackvariables = null;
         }
         $question->prts[$name] = new stack_potentialresponse_tree($name, '', (bool) $prtdata->autosimplify, $prtdata->value / $totalvalue, $feedbackvariables, $nodes, $prtdata->firstnodename);
     }
     $question->deployedseeds = array_values($questiondata->deployedseeds);
 }
 public function test_validate_student_response_allowwords_true()
 {
     $options = new stack_options();
     $el = stack_input_factory::make('algebraic', 'sans1', '2*x');
     $el->set_parameter('allowWords', 'pop, funney1, unknownfunction');
     $state = $el->validate_student_response(array('sans1' => 'unknownfunction(x^2+1)+3*x'), $options, '2*x', array('ta'));
     $this->assertEquals(stack_input::VALID, $state->status);
 }
 protected function make_dropdown()
 {
     $el = stack_input_factory::make('dropdown', 'ans1', 'x+1');
     $el->set_parameter('ddl_values', 'x+1,x+2,x+3');
     return $el;
 }
 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());
 }
 public function test_render_disabled()
 {
     $el = stack_input_factory::make('boolean', 'input', stack_boolean_input::T);
     $this->assert(new question_contains_select_expectation('stack1__ans1', $this->expected_choices(), stack_boolean_input::NA, false), $el->render(new stack_input_state(stack_input::BLANK, array(), '', '', '', '', ''), 'stack1__ans1', true));
 }
Beispiel #10
0
 public static function make_stack_question_runtime_prt_err()
 {
     $q = self::make_a_stack_question();
     $q->name = 'runtime_prt_err';
     $q->questionvariables = "";
     $q->questiontext = '<p>Give an example of a system of equations with a unique solution.</p>' . '<p>[[input:ans1]] [[validation:ans1]]</p>';
     $q->specificfeedback = '[[feedback:Result]]';
     $q->questionnote = '';
     $q->inputs['ans1'] = stack_input_factory::make('algebraic', 'ans1', '[x+y=1,x-y=1]', array('boxWidth' => 25));
     $feedbackvars = new stack_cas_keyval('', null, 0, 't');
     $sans = new stack_cas_casstring('all_listp(equationp,ans1)');
     $sans->get_valid('t');
     $tans = new stack_cas_casstring('true');
     $tans->get_valid('t');
     $node0 = new stack_potentialresponse_node($sans, $tans, 'AlgEquiv', '', true);
     $node0->add_branch(0, '=', 0, '', -1, 'Your answer should be a list of equations!', FORMAT_HTML, 'Result-0-F');
     $node0->add_branch(1, '=', 0, '', 1, 'Your answer is a list of equations.', FORMAT_HTML, 'Result-0-T');
     $sans = new stack_cas_casstring('solve(ans1,listofvars(ans1))');
     $sans->get_valid('t');
     $tans = new stack_cas_casstring('[]');
     $tans->get_valid('t');
     $node1 = new stack_potentialresponse_node($sans, $tans, 'AlgEquiv', '', true);
     $node1->add_branch(0, '=', 0, $q->penalty, -1, 'Your equations have no solution!', FORMAT_HTML, 'Result-1-F');
     $node1->add_branch(1, '=', 0, $q->penalty, 2, 'You have some solutions!', FORMAT_HTML, 'Result-1-T');
     $sans = new stack_cas_casstring('length(solve(ans1,listofvars(ans1)))');
     $sans->get_valid('t');
     $tans = new stack_cas_casstring('1');
     $tans->get_valid('t');
     $node2 = new stack_potentialresponse_node($sans, $tans, 'AlgEquiv', '', true);
     $node2->add_branch(0, '=', 0, $q->penalty, -1, 'You should have only one solution.', FORMAT_HTML, 'Result-2-F');
     $node2->add_branch(1, '=', 1, $q->penalty, -1, 'Good, you have one solution.', FORMAT_HTML, 'Result-2-T');
     $q->prts['Result'] = new stack_potentialresponse_tree('Result', '', true, 1, $feedbackvars->get_session(), array($node0, $node1, $node2), 0);
     return $q;
 }
 public function test_render_disabled()
 {
     $el = stack_input_factory::make('singleChar', 'input', null);
     $expected = '<input type="text" name="question__stack1" id="question__stack1" size="1" maxlength="1" ' . 'value="a" readonly="readonly" />';
     $this->assertEquals($expected, $el->render(new stack_input_state(stack_input::VALID, array('a'), '', '', '', '', ''), 'question__stack1', true));
 }
 /**
  * Return array of the default option values for each type of input,
  * for use in authoring interface.
  * @return array $typename => array of option names => default.
  */
 public static function get_parameters_defaults()
 {
     if (!is_null(self::$parametersdefaults)) {
         return self::$parametersdefaults;
     }
     self::$parametersdefaults = array();
     foreach (self::get_available_types() as $type => $class) {
         self::$parametersdefaults[$type] = $class::get_parameters_defaults();
     }
     return self::$parametersdefaults;
 }
 public function test_render_disabled()
 {
     $el = stack_input_factory::make('textArea', 'input', null);
     $this->assertEquals('<textarea name="st_ans1" id="st_ans1" rows="5" cols="20" readonly="readonly"></textarea>', $el->render(new stack_input_state(stack_input::BLANK, array(), '', '', '', '', ''), 'st_ans1', true));
 }