public function subquestion(question_attempt $qa, question_display_options $options, qtype_combined_combinable_base $subq, $placeno) { $question = $subq->question; $place = $placeno + 1; $group = $question->places[$place]; $fieldname = $subq->step_data_name($question->field($place)); $value = $qa->get_last_qt_var($fieldname); $attributes = array('id' => str_replace(':', '_', $qa->get_qt_field_name($fieldname))); if ($options->readonly) { $attributes['disabled'] = 'disabled'; } $orderedchoices = $question->get_ordered_choices($group); $selectoptions = array(); foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) { $selectoptions[$orderedchoicevalue] = $orderedchoice->text; } $feedbackimage = ''; if ($options->correctness) { $response = $qa->get_last_qt_data(); if (array_key_exists($fieldname, $response)) { $fraction = (int) ($response[$fieldname] == $question->get_right_choice_for($place)); $attributes['class'] = $this->feedback_class($fraction); $feedbackimage = $this->feedback_image($fraction); } } $selecthtml = html_writer::select($selectoptions, $qa->get_qt_field_name($fieldname), $value, get_string('choosedots'), $attributes) . ' ' . $feedbackimage; return html_writer::tag('span', $selecthtml, array('class' => 'control')); }
protected function embedded_element(question_attempt $qa, $place, question_display_options $options) { $question = $qa->get_question(); $group = $question->places[$place]; $fieldname = $question->field($place); $value = $qa->get_last_qt_var($question->field($place)); $attributes = array('id' => $this->box_id($qa, 'p' . $place)); $groupclass = 'group' . $group; if ($options->readonly) { $attributes['disabled'] = 'disabled'; } $orderedchoices = $question->get_ordered_choices($group); $selectoptions = array(); foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) { $selectoptions[$orderedchoicevalue] = $orderedchoice->text; } $feedbackimage = ''; if ($options->correctness) { $response = $qa->get_last_qt_data(); if (array_key_exists($fieldname, $response)) { $fraction = (int) ($response[$fieldname] == $question->get_right_choice_for($place)); $attributes['class'] = $this->feedback_class($fraction); $feedbackimage = $this->feedback_image($fraction); } } $selecthtml = html_writer::select($selectoptions, $qa->get_qt_field_name($fieldname), $value, get_string('choosedots'), $attributes) . ' ' . $feedbackimage; return html_writer::tag('span', $selecthtml, array('class' => 'control ' . $groupclass)); }
public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); $answer = $question->get_matching_answer(array('answer' => $qa->get_last_qt_var('answer'))); if (!$answer || !$answer->feedback) { return ''; } return $question->format_text($answer->feedback, $answer->feedbackformat, $qa, 'question', 'answerfeedback', $answer->id); }
public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); $response = array(); foreach ($question->get_parameters() as $param) { $response['answer_' . $param] = $qa->get_last_qt_var('answer_' . $param); } $question->compute_feedbackperconditions($response); return $question->computedfeedbackperconditions; }
public function embedded_element(question_attempt $qa, $place, question_display_options $options, $marked_gaps) { /* fraction is the mark associated with this field, always 1 or 0 for this question type */ $question = $qa->get_question(); $fieldname = $question->field($place); $currentanswer = $qa->get_last_qt_var($fieldname); $rightanswer = $question->get_right_choice_for($place); $size = strlen($rightanswer); /* $options->correctness is really about it being ready to mark, */ $feedbackimage = ""; $inputclass = ""; if ($options->correctness or $options->numpartscorrect) { $gap = $marked_gaps['p' . $place]; $fraction = $gap['fraction']; $response = $qa->get_last_qt_data(); if ($fraction == 1) { array_push($this->correct_responses, $response[$fieldname]); $feedbackimage = $this->feedback_image($fraction); /* sets the field background to green or yellow if fraction is 1 */ $inputclass = $this->get_input_class($marked_gaps, $qa, $fraction, $fieldname); } else { /* set background to red and image to cross if fraction is 0 */ $feedbackimage = $this->feedback_image($fraction); $inputclass = $this->feedback_class($fraction); } } $qprefix = $qa->get_qt_field_name(''); $inputname = $qprefix . 'p' . $place; $inputattributes = array('type' => "text", 'name' => $inputname, 'value' => $currentanswer, 'id' => $inputname, 'size' => $size, 'class' => 'droppable ' . $inputclass); /* When previewing after a quiz is complete */ if ($options->readonly) { $readonly = array('disabled' => 'true'); $inputattributes = array_merge($inputattributes, $readonly); } if ($question->answerdisplay == "dropdown") { $inputattributes['type'] = "select"; $inputattributes['size'] = ""; $inputattributes['class'] = $inputclass; $answers = $qa->get_step(0)->get_qt_var('_allanswers'); $selectoptions = $this->get_answers('dropdown', $answers); $selecthtml = html_writer::select($selectoptions, $inputname, $currentanswer, ' ', $inputattributes) . ' ' . $feedbackimage; return $selecthtml; } else { return html_writer::empty_tag('input', $inputattributes) . $feedbackimage; } }
protected function embedded_element(question_attempt $qa, $place, question_display_options $options) { $question = $qa->get_question(); $group = $question->places[$place]; $boxcontents = ' ' . html_writer::tag('span', get_string('blank', 'qtype_ddwtos'), array('class' => 'accesshide')); $value = $qa->get_last_qt_var($question->field($place)); $attributes = array('class' => 'place' . $place . ' drop group' . $group); if ($options->readonly) { $attributes['class'] .= ' readonly'; } else { $attributes['tabindex'] = '0'; } $feedbackimage = ''; if ($options->correctness) { $response = $qa->get_last_qt_data(); $fieldname = $question->field($place); if (array_key_exists($fieldname, $response)) { $fraction = (int) ($response[$fieldname] == $question->get_right_choice_for($place)); $feedbackimage = $this->feedback_image($fraction); } } return html_writer::tag('span', $boxcontents, $attributes) . ' ' . $feedbackimage; }
public function subquestion(question_attempt $qa, question_display_options $options, $index, question_graded_automatically $subq) { $fieldprefix = 'sub' . $index . '_'; $fieldname = $fieldprefix . 'answer'; $response = $qa->get_last_qt_var($fieldname); $inputattributes = array( 'type' => 'radio', 'name' => $qa->get_qt_field_name($fieldname), ); if ($options->readonly) { $inputattributes['disabled'] = 'disabled'; } $result = $this->all_choices_wrapper_start(); $fraction = null; foreach ($subq->get_order($qa) as $value => $ansid) { $ans = $subq->answers[$ansid]; $inputattributes['value'] = $value; $inputattributes['id'] = $inputattributes['name'] . $value; $isselected = $subq->is_choice_selected($response, $value); if ($isselected) { $inputattributes['checked'] = 'checked'; $fraction = $ans->fraction; } else { unset($inputattributes['checked']); } $class = 'r' . ($value % 2); if ($options->correctness && $isselected) { $feedbackimg = $this->feedback_image($ans->fraction); $class .= ' ' . $this->feedback_class($ans->fraction); } else { $feedbackimg = ''; } $result .= $this->choice_wrapper_start($class); $result .= html_writer::empty_tag('input', $inputattributes); $result .= html_writer::tag('label', $subq->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ansid), array('for' => $inputattributes['id'])); $result .= $feedbackimg; if ($options->feedback && $isselected && trim($ans->feedback)) { $result .= html_writer::tag('div', $subq->format_text($ans->feedback, $ans->feedbackformat, $qa, 'question', 'answerfeedback', $ansid), array('class' => 'specificfeedback')); } $result .= $this->choice_wrapper_end(); } $result .= $this->all_choices_wrapper_end(); $feedback = array(); if ($options->feedback && $options->marks >= question_display_options::MARK_AND_MAX && $subq->maxmark > 0) { $a = new stdClass(); $a->mark = format_float($fraction * $subq->maxmark, $options->markdp); $a->max = format_float($subq->maxmark, $options->markdp); $feedback[] = html_writer::tag('div', get_string('markoutofmax', 'question', $a)); } if ($options->rightanswer) { foreach ($subq->answers as $ans) { if (question_state::graded_state_for_fraction($ans->fraction) == question_state::$gradedright) { $feedback[] = get_string('correctansweris', 'qtype_multichoice', $subq->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ansid)); break; } } } $result .= html_writer::nonempty_tag('div', implode('<br />', $feedback), array('class' => 'outcome')); return $result; }
public function get_response(question_attempt $qa) { return $qa->get_last_qt_var('answer', -1); }
public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); if ($question->unitdisplay == qtype_numerical::UNITSELECT) { $selectedunit = $qa->get_last_qt_var('unit'); } else { $selectedunit = null; } list($value, $unit) = $question->ap->apply_units( $qa->get_last_qt_var('answer'), $selectedunit); $answer = $question->get_matching_answer($value); if ($answer && $answer->feedback) { $feedback = $question->format_text($answer->feedback, $answer->feedbackformat, $qa, 'question', 'answerfeedback', $answer->id); } else { $feedback = ''; } if ($question->unitgradingtype && !$question->ap->is_known_unit($unit)) { $feedback .= html_writer::tag('p', get_string('unitincorrect', 'qtype_numerical')); } return $feedback; }
protected function hidden_field_for_qt_var(question_attempt $qa, $varname) { $value = $qa->get_last_qt_var($varname, ''); $fieldname = $qa->get_qt_field_name($varname); $attributes = array('type' => 'hidden', 'id' => str_replace(':', '_', $fieldname), 'class' => $varname, 'name' => $fieldname, 'value' => $value); return html_writer::empty_tag('input', $attributes); }
protected function get_last_response(question_attempt $qa) { $question = $qa->get_question(); $responsefields = array_keys($question->get_expected_data()); $response = array(); foreach ($responsefields as $responsefield) { $response[$responsefield] = $qa->get_last_qt_var($responsefield); } return $response; }
public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); $response = $qa->get_last_qt_var('answer', ''); if ($response) { return $question->format_text($question->truefeedback, $question->truefeedbackformat, $qa, 'question', 'answerfeedback', $question->trueanswerid); } else { if ($response !== '') { return $question->format_text($question->falsefeedback, $question->falsefeedbackformat, $qa, 'question', 'answerfeedback', $question->falseanswerid); } } }
/** * Gereate the specific feedback. This is feedback that varies according to * the reponse the student gave. * This code tries to allow for the possiblity that the question is being * used with the wrong (i.e. non-adaptive) behaviour, which would mean that * test results aren't available. * @param question_attempt $qa the question attempt to display. * @return string HTML fragment. */ protected function specific_feedback(question_attempt $qa) { $toserialised = $qa->get_last_qt_var('_testoutcome'); if ($toserialised) { $q = $qa->get_question(); $testcases = $q->testcases; $testoutcome = unserialize($toserialised); $testresults = $testoutcome->testresults; if ($testoutcome->all_correct()) { $resultsclass = "coderunner-test-results good"; } else { if (!$q->allornothing && $testoutcome->mark_as_fraction() > 0) { $resultsclass = 'coderunner-test-results partial'; } else { $resultsclass = "coderunner-test-results bad"; } } $fb = ''; if ($q->showsource && count($testoutcome->sourcecodelist) > 0) { $fb .= $this->make_source_code_div('Debug: source code from all test runs', $testoutcome->sourcecodelist); } $fb .= html_writer::start_tag('div', array('class' => $resultsclass)); // Hack to insert run host as hidden comment in html $fb .= "\n<!-- Run on {$testoutcome->runhost} -->\n"; if ($testoutcome->run_failed()) { $fb .= html_writer::tag('h3', get_string('run_failed', 'qtype_coderunner')); $fb .= html_writer::tag('p', s($testoutcome->errormessage), array('class' => 'run_failed_error')); } else { if ($testoutcome->has_syntax_error()) { $fb .= html_writer::tag('h3', get_string('syntax_errors', 'qtype_coderunner')); $fb .= html_writer::tag('pre', s($testoutcome->errormessage), array('class' => 'pre_syntax_error')); } else { if ($testoutcome->feedbackhtml) { $fb .= $testoutcome->feedbackhtml; } else { $fb .= html_writer::tag('p', ' ', array('class' => 'coderunner-spacer')); $results = $this->build_results_table($q, $testcases, $testresults); if ($results != null) { $fb .= $results; } } } } // Summarise the status of the response in a paragraph at the end. if (!$testoutcome->has_syntax_error() && !$testoutcome->run_failed() && !$testoutcome->feedbackhtml) { $fb .= $this->build_feedback_summary($q, $testcases, $testoutcome); } $fb .= html_writer::end_tag('div'); } else { // No testresults?! Probably due to a wrong behaviour selected $text = get_string('qWrongBehaviour', 'qtype_coderunner'); $fb = html_writer::start_tag('div', array('class' => 'missingResults')); $fb .= html_writer::tag('p', $text); $fb .= html_writer::end_tag('div'); } return $fb; }
/** * Returns a hidden field for a qt variable * * @param object $qa Question attempt object * @param string $varname The hidden var name * @param string $value The hidden value * @param array $classes Any additional css classes to apply * @return array Array with field name and the html of the tag */ protected function hidden_field_for_qt_var(question_attempt $qa, $varname, $value = null, $classes = null) { if ($value === null) { $value = $qa->get_last_qt_var($varname); } $fieldname = $qa->get_qt_field_name($varname); $attributes = array('type' => 'hidden', 'id' => str_replace(':', '_', $fieldname), 'name' => $fieldname, 'value' => $value); if ($classes !== null) { $attributes['class'] = join(' ', $classes); } return array($fieldname, html_writer::empty_tag('input', $attributes) . "\n"); }
public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); $currentanswer = remove_blanks($qa->get_last_qt_var('answer')); $ispreview = false; $completemessage = ''; $closestcomplete = false; foreach ($qa->get_reverse_step_iterator() as $step) { $hintadded = $step->has_behaviour_var('_helps') === true; break; } $closest = $question->closest; if ($hintadded) { // hint added one letter or hint added letter and answer is complete $answer = $question->get_matching_answer(array('answer' => $closest[0])); // help has added letter OR word and answer is complete $isstateimprovable = $qa->get_behaviour()->is_state_improvable($qa->get_state()); if ($closest[2] == 'complete' && $isstateimprovable) { $closestcomplete = true; $class = '"correctness correct"'; $completemessage = '<div class=' . $class . '>' . get_string("clicktosubmit", "qtype_regexp") . '</div>'; } } else { $answer = $question->get_matching_answer(array('answer' => $qa->get_last_qt_var('answer'))); } if ($closest[3]) { $closest[3] = '[' . $closest[3] . ']'; // rest of submitted answer, in red } $f = ''; // student's response with corrections to be displayed in feedback div $f = '<span style="color:#0000FF;">' . $closest[1] . '<strong>' . $closest[4] . '</strong></span> ' . $closest[3]; // color blue for correct words/letters if ($answer && $answer->feedback || $closestcomplete == true) { return $question->format_text($f . $answer->feedback . $completemessage, $answer->feedbackformat, $qa, 'question', 'answerfeedback', $answer->id); } else { return $f; } }