function find_closest($question, $currentanswer, $correct_response = false, $hintadded = false) { global $CFG; // JR dec 2011 moved get alternate answers to new function $alternateanswers = get_alternateanswers($question); $alternatecorrectanswers = array(); // JR jan 2012 changed contents of alternateanswers if (isset($question->id)) { $qid = $question->id; if (!isset($SESSION->qtype_regexp_question->alternatecorrectanswers[$qid])) { foreach ($alternateanswers as $key => $alternateanswer) { foreach ($alternateanswer['answers'] as $alternate) { $alternatecorrectanswers[] = $alternate; } } $SESSION->qtype_regexp_question->alternatecorrectanswers[$qid] = $alternatecorrectanswers; } } // testing ignorecase $ignorecase = 'i'; if ($question->usecase) { $ignorecase = ''; } // only use ishint value if hint button has been clicked $ishint = $question->usehint * $hintadded; // find closest answer matching student response if (!isset($currentanswer) && !$correct_response) { return null; } if ($correct_response) { return $alternatecorrectanswers; } $closest = get_closest($currentanswer, $alternatecorrectanswers, $ignorecase, $ishint); if ($closest[2] == 'complete') { return $closest; } // give first character of firstcorrectanswer to student (if option usehint for this question) // TODO JR maybe not? /*if ($closest[0] == '' && ($question->usehint == true) && $closest[2] == 'nil' ) { $closest[0] = $textlib->substr($firstcorrectanswer, 0, 1); }*/
/** * Add question-type specific form fields. * * @param MoodleQuickForm $mform the form being built. */ protected function definition_inner($mform) { global $CFG, $OUTPUT, $SESSION; require_once $CFG->dirroot . '/question/type/regexp/locallib.php'; $this->showalternate = false; if ("" != optional_param('showalternate', '', PARAM_RAW)) { $this->showalternate = true; $this->questionid = optional_param('id', '', PARAM_NOTAGS); $this->usecase = optional_param('usecase', '', PARAM_NOTAGS); $this->studentshowalternate = optional_param('studentshowalternate', '', PARAM_NOTAGS); $this->fraction = optional_param_array('fraction', '', PARAM_RAW); $this->currentanswers = optional_param_array('answer', '', PARAM_NOTAGS); //$this->feedback = optional_param('feedback', '', PARAM_NOTAGS); // no longer works in moodle 2.2 and later see http://moodle.org/mod/forum/discuss.php?d=197118 // so use data_submitted() instead $feedback = data_submitted()->feedback; // we only need to get the feedback text, for validation purposes when showalternate is requested foreach ($feedback as $key => $fb) { $this->feedback[$key]['text'] = clean_param($fb['text'], PARAM_NOTAGS); } } // JR added advanced settings to hide mostly unwanted hints and tags settings if ("" != optional_param('addhint', '', PARAM_RAW)) { $this->hints = optional_param('hint', '', PARAM_NOTAGS); } elseif (isset($this->question->hints)) { $this->hints = $this->question->hints; } $counthints = 0; if (isset($this->hints)) { $counthints = count($this->hints); } $mform->setAdvanced('tags'); for ($i = 0; $i < $counthints; $i++) { $mform->setAdvanced("hint[{$i}]"); } // hint mode :: None / Letter / Word $menu = array(get_string('none'), get_string('letter', 'qtype_regexp'), get_string('word', 'qtype_regexp')); $mform->addElement('select', 'usehint', get_string('usehint', 'qtype_regexp'), $menu); $mform->addHelpButton('usehint', 'usehint', 'qtype_regexp'); // use case :: yes / no $menu = array(get_string('caseno', 'qtype_regexp'), get_string('caseyes', 'qtype_regexp')); $mform->addElement('select', 'usecase', get_string('casesensitive', 'qtype_regexp'), $menu); // display all correct alternate answers to student on review page :: yes / no $menu = array(get_string('no'), get_string('yes')); $mform->addElement('select', 'studentshowalternate', get_string('studentshowalternate', 'qtype_regexp'), $menu); $mform->addHelpButton('studentshowalternate', 'studentshowalternate', 'qtype_regexp'); //$mform->closeHeaderBefore('answersinstruct'); $mform->addElement('static', 'answersinstruct', 'Note.-', get_string('filloutoneanswer', 'qtype_regexp')); $this->add_per_answer_fields($mform, get_string('answerno', 'qtype_shortanswer', '{no}'), question_bank::fraction_options(), $minoptions = 3, $addoptions = 1); $mform->addElement('header', 'showhidealternate', get_string('showhidealternate', 'qtype_regexp')); $mform->addHelpButton('showhidealternate', 'showhidealternate', 'qtype_regexp'); $buttonarray = array(); $buttonarray[] = $mform->createElement('submit', 'showalternate', get_string('showalternate', 'qtype_regexp')); $mform->registerNoSubmitButton('showalternate'); if ($this->showalternate) { $qu = new stdClass(); $qu->id = $this->questionid; $qu->answers = array(); $i = 0; $this->fraction[0] = 1; $data = array(); foreach ($this->currentanswers as $key => $answer) { $qu->answers[$i] = new stdClass(); $qu->answers[$i]->answer = $answer; $qu->answers[$i]->fraction = $this->fraction[$i]; // for sending $data to validation $data['answer'][$i] = $answer; $data['fraction'][$i] = $this->fraction[$i]; $data['feedback'][$i] = $this->feedback[$i]; $i++; } $moodle_val = $this->validation($data, ''); if (is_array($moodle_val) && count($moodle_val) !== 0) { // non-empty array means errors foreach ($moodle_val as $element => $msg) { $mform->setElementError($element, $msg); } // set to false in order to set hidealternate button to disabled $this->showalternate = false; } else { // we need to unset SESSION in case Answers have been edited since last call to get_alternateanswers() if (isset($SESSION->qtype_regexp_question->alternateanswers[$this->questionid])) { unset($SESSION->qtype_regexp_question->alternateanswers[$this->questionid]); } $alternateanswers = get_alternateanswers($qu); $mform->addElement('html', '<div class="alternateanswers">'); $alternatelist = ''; foreach ($alternateanswers as $key => $alternateanswer) { $mform->addElement('static', 'alternateanswer', get_string('answer') . ' ' . $key . ' (' . $alternateanswer['fraction'] . ')', '<span class="regexp">' . $alternateanswer['regexp'] . '</span>'); $list = ''; foreach ($alternateanswer['answers'] as $alternate) { $list .= '<li>' . $alternate . '</li>'; } $mform->addElement('static', 'alternateanswer', '', '<ul class="square">' . $list . '</ul>'); } $mform->addElement('html', '</div>'); } } $disabled = ''; if ($this->showalternate) { $disabled = ''; } else { $disabled = 'disabled'; } $buttonarray[] = $mform->createElement('submit', 'hidealternate', get_string('hidealternate', 'qtype_regexp'), $disabled); $mform->registerNoSubmitButton('hidealternate'); $mform->addGroup($buttonarray, '', '', array(' '), false); $mform->addElement('header', 'multitriesheader', get_string('settingsformultipletries', 'qtype_regexp')); $withclearwrong = false; $withshownumpartscorrect = false; $penalties = array(1.0, 0.5, 0.33, 0.25, 0.2, 0.1, 0.05, 0.0); if (!empty($this->question->penalty) && !in_array($this->question->penalty, $penalties)) { $penalties[] = $this->question->penalty; sort($penalties); } $penaltyoptions = array(); foreach ($penalties as $penalty) { $penaltyoptions["{$penalty}"] = 100 * $penalty . '%'; } $mform->addElement('select', 'penalty', get_string('penaltyforeachincorrecttry', 'qtype_regexp'), $penaltyoptions); $mform->addRule('penalty', null, 'required', null, 'client'); $mform->addHelpButton('penalty', 'penaltyforeachincorrecttry', 'qtype_regexp'); $mform->setDefault('penalty', 0.1); if ($this->question->formoptions->repeatelements) { //$repeatsatstart = max(self::DEFAULT_NUM_HINTS, $counthints); // JR we suppose hints are not really needed in REGEXP question type, so set start nb at zero $repeatsatstart = max(0, $counthints); } else { $repeatsatstart = $counthints; } if ($counthints != 0) { $addhint = get_string('addanotherhint', 'question'); } else { $addhint = get_string('addahint', 'qtype_regexp'); } list($repeated, $repeatedoptions) = $this->get_hint_fields($withclearwrong, $withshownumpartscorrect); $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'numhints', 'addhint', 1, $addhint); }
public function correct_response(question_attempt $qa) { $question = $qa->get_question(); $display_responses = ''; $alternateanswers = get_alternateanswers($question); $bestcorrectanswer = $alternateanswers[1]['answers'][0]; if (count($alternateanswers) == 1) { // no alternative answers besides the only "correct" answer $display_responses .= get_string('correctansweris', 'qtype_regexp', $bestcorrectanswer); } else { $display_responses .= get_string('bestcorrectansweris', 'qtype_regexp', $bestcorrectanswer) . '<br />'; } if ($question->studentshowalternate) { foreach ($alternateanswers as $key => $alternateanswer) { if ($key == 1) { // first (correct) Answer $display_responses .= get_string('correctanswersare', 'qtype_regexp') . '<br />'; } else { $fraction = $alternateanswer['fraction']; $display_responses .= "<strong>{$fraction}</strong><br>"; foreach ($alternateanswer['answers'] as $alternate) { $display_responses .= $alternate . '<br />'; } } } } return $display_responses; }