mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-12418 "Item Analysis shows duplicate responses for Multiple Choice questions with LaTeX in answers" This problem was caused by the formatting of questions in get_actual_responses. Now formatting is done in response_summary rather than get_actual_response which returns an array of unformatted strings.
Have fixed the formatting in responses report and in statistics report to use the correct formatting for the question type. Created new functions format_responses and format_response. format_responses works on an array and normally just walks through the array calling format_response.
This commit is contained in:
parent
d54e2145ba
commit
2280e147c5
@ -137,6 +137,7 @@ class quiz_report_responses_table extends table_sql {
|
||||
}
|
||||
}
|
||||
function other_cols($colname, $attempt){
|
||||
global $QTYPES;
|
||||
static $states =array();
|
||||
if (preg_match('/^qsanswer([0-9]+)$/', $colname, $matches)){
|
||||
if ($attempt->uniqueid == 0) {
|
||||
@ -152,41 +153,37 @@ class quiz_report_responses_table extends table_sql {
|
||||
$question = $this->questions[$questionid];
|
||||
restore_question_state($question, $stateforqinattempt);
|
||||
|
||||
if ($responses = get_question_actual_response($question, $stateforqinattempt)){
|
||||
$response = (!empty($responses)? implode('; ',$responses) : '-');
|
||||
if (!$this->is_downloading() || $this->is_downloading() == 'xhtml'){
|
||||
$formathtml = true;
|
||||
} else {
|
||||
$response = '';
|
||||
$formathtml = false;
|
||||
}
|
||||
|
||||
$summary = $QTYPES[$question->qtype]->response_summary($question, $stateforqinattempt,
|
||||
QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY, $formathtml);
|
||||
if (!$this->is_downloading()) {
|
||||
if ($response){
|
||||
$format_options = new stdClass;
|
||||
$format_options->para = false;
|
||||
$format_options->newlines = false;
|
||||
$response = format_text($response, FORMAT_MOODLE, $format_options);
|
||||
if (strlen($response) > QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY){
|
||||
$response = shorten_text($response, QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY);
|
||||
}
|
||||
$response = link_to_popup_window('/mod/quiz/reviewquestion.php?attempt=' .
|
||||
if ($summary){
|
||||
$summary = link_to_popup_window('/mod/quiz/reviewquestion.php?attempt=' .
|
||||
$attempt->attempt . '&question=' . $question->id,
|
||||
'reviewquestion', $response, 450, 650, get_string('reviewresponse', 'quiz'),
|
||||
'reviewquestion', $summary, 450, 650, get_string('reviewresponse', 'quiz'),
|
||||
'none', true);
|
||||
if (question_state_is_graded($stateforqinattempt)
|
||||
&& ($this->questions[$questionid]->maxgrade != 0)){
|
||||
&& ($question->maxgrade != 0)){
|
||||
$grade = $stateforqinattempt->grade
|
||||
/ $this->questions[$questionid]->maxgrade;
|
||||
/ $question->maxgrade;
|
||||
$qclass = question_get_feedback_class($grade);
|
||||
$feedbackimg = question_get_feedback_image($grade);
|
||||
$questionclass = "que";
|
||||
return "<span class=\"$questionclass\"><span class=\"$qclass\">".$response."</span></span>$feedbackimg";
|
||||
return "<span class=\"$questionclass\"><span class=\"$qclass\">".$summary."</span></span>$feedbackimg";
|
||||
} else {
|
||||
return $response;
|
||||
return $summary;
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
} else {
|
||||
return $this->format_text($response);
|
||||
return $summary;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
|
@ -228,7 +228,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
print_heading(get_string('questioninformation', 'quiz_statistics'));
|
||||
print_table($questioninfotable);
|
||||
|
||||
print_box(format_text($question->questiontext).$actions, 'boxaligncenter generalbox boxwidthnormal mdl-align');
|
||||
print_box(format_text($question->questiontext, $question->questiontextformat).$actions, 'boxaligncenter generalbox boxwidthnormal mdl-align');
|
||||
|
||||
print_heading(get_string('questionstatistics', 'quiz_statistics'));
|
||||
print_table($questionstatstable);
|
||||
|
@ -57,6 +57,15 @@ class quiz_report_statistics_question_table extends flexible_table {
|
||||
parent::setup();
|
||||
}
|
||||
|
||||
function col_response($response){
|
||||
global $QTYPES;
|
||||
if (!$this->is_downloading() || $this->is_downloading() == 'xhtml'){
|
||||
return $QTYPES[$this->question->qtype]->format_response($response->response, $this->question->questiontextformat);
|
||||
} else {
|
||||
return $response->response;
|
||||
}
|
||||
}
|
||||
|
||||
function col_subq($response){
|
||||
return $response->subq;
|
||||
}
|
||||
|
@ -695,7 +695,7 @@ class question_calculated_qtype extends default_questiontype {
|
||||
return $virtualqtype->grade_responses($numericalquestion, $state, $cmoptions) ;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length=80) {
|
||||
function response_summary($question, $state, $length=80, $formatting=true) {
|
||||
// The actual response is the bit after the hyphen
|
||||
return substr($state->answer, strpos($state->answer, '-')+1, $length);
|
||||
}
|
||||
|
@ -116,11 +116,6 @@ class question_essay_qtype extends default_questiontype {
|
||||
return true;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length = 80) {
|
||||
$responses = $this->get_actual_response($question, $state);
|
||||
$response = reset($responses);
|
||||
return shorten_text($response, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup the extra information specific to an essay question - over and above
|
||||
|
@ -465,10 +465,7 @@ class question_match_qtype extends default_questiontype {
|
||||
}
|
||||
return $responsedetails;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length=80) {
|
||||
return shorten_text(implode(', ', $this->get_actual_response($question, $state)), $length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
|
@ -653,9 +653,7 @@ class embedded_cloze_qtype extends default_questiontype {
|
||||
$teststate->responses = array('' => $state->responses[$key]);
|
||||
$correct = $QTYPES[$wrapped->qtype]
|
||||
->get_actual_response($wrapped, $teststate);
|
||||
// change separator here if you want
|
||||
$responsesseparator = ',';
|
||||
$responses[$key] = implode($responsesseparator, $correct);
|
||||
$responses[$key] = implode(';', $correct);
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ class question_multichoice_qtype extends default_questiontype {
|
||||
if (!empty($state->responses)) {
|
||||
foreach ($state->responses as $aid =>$rid){
|
||||
if (!empty($answers[$rid])) {
|
||||
$responses[] = $this->format_text($answers[$rid]->answer, $question->questiontextformat);
|
||||
$responses[] = $answers[$rid]->answer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -396,8 +396,9 @@ class question_multichoice_qtype extends default_questiontype {
|
||||
return $responses;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length = 80) {
|
||||
return implode(',', $this->get_actual_response($question, $state));
|
||||
|
||||
function format_response($response, $format){
|
||||
return $this->format_text($response, $format);
|
||||
}
|
||||
/**
|
||||
* @param object $question
|
||||
|
@ -725,9 +725,9 @@ class default_questiontype {
|
||||
function get_random_guess_score($question) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
/**
|
||||
* Return the actual response to the question in a given state
|
||||
* for the question.
|
||||
* for the question. Text is not yet formatted for output.
|
||||
*
|
||||
* @return mixed An array containing the response or reponses (multiple answer, match)
|
||||
* given by the user in a particular attempt.
|
||||
@ -1233,25 +1233,40 @@ class default_questiontype {
|
||||
*
|
||||
* This function returns a short string of no more than a given length that
|
||||
* summarizes the student's response in the given $state. This is used for
|
||||
* example in the response history table. This string should already be,
|
||||
* for output.
|
||||
* example in the response history table. This string should already be
|
||||
* formatted for output.
|
||||
* @return string The summary of the student response
|
||||
* @param object $question
|
||||
* @param object $state The state whose responses are to be summarized
|
||||
* @param int $length The maximum length of the returned string
|
||||
*/
|
||||
function response_summary($question, $state, $length=80) {
|
||||
function response_summary($question, $state, $length=80, $formatting=true) {
|
||||
// This should almost certainly be overridden
|
||||
$responses = $this->get_actual_response($question, $state);
|
||||
if (empty($responses) || !is_array($responses)) {
|
||||
$responses = array();
|
||||
}
|
||||
if (is_array($responses)) {
|
||||
$responses = implode(',', array_map('s', $responses));
|
||||
if ($formatting){
|
||||
$responses = $this->format_responses($responses, $question->questiontextformat);
|
||||
}
|
||||
$responses = implode(';', $responses);
|
||||
return shorten_text($responses, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array responses is an array of responses.
|
||||
* @return formatted responses
|
||||
*/
|
||||
function format_responses($responses, $format){
|
||||
$toreturn = array();
|
||||
foreach ($responses as $response){
|
||||
$toreturn[] = $this->format_response($response, $format);
|
||||
}
|
||||
return $toreturn;
|
||||
}
|
||||
/**
|
||||
* @param string response is a response.
|
||||
* @return formatted response
|
||||
*/
|
||||
function format_response($response, $format){
|
||||
return s($response);
|
||||
}
|
||||
/**
|
||||
* Renders the question for printing and returns the LaTeX source produced
|
||||
*
|
||||
|
@ -228,15 +228,6 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
return true;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length=80) {
|
||||
if (isset($question->options->answers[$state->answer])) {
|
||||
$responses = $question->options->answers[$state->answer]->answer;
|
||||
} else {
|
||||
$responses = '';
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
||||
function get_actual_response($question, $state) {
|
||||
if (isset($question->options->answers[$state->responses['']])) {
|
||||
$responses[] = $question->options->answers[$state->responses['']]->answer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user