public function feedback(question_attempt $qa, question_display_options $options)
 {
     // Try to find the last graded step.
     $gradedstep = $this->get_graded_step($qa);
     if (is_null($gradedstep) || $qa->get_max_mark() == 0 || $options->marks < question_display_options::MARK_AND_MAX) {
         return '';
     }
     // Display the grading details from the last graded state
     $mark = new stdClass();
     $mark->max = $qa->format_max_mark($options->markdp);
     $actualmark = $gradedstep->get_fraction() * $qa->get_max_mark();
     $mark->cur = format_float($actualmark, $options->markdp);
     $rawmark = $gradedstep->get_behaviour_var('_rawfraction') * $qa->get_max_mark();
     $mark->raw = format_float($rawmark, $options->markdp);
     // let student know wether the answer was correct
     if ($qa->get_state()->is_commented()) {
         $class = $qa->get_state()->get_feedback_class();
     } else {
         $class = question_state::graded_state_for_fraction($gradedstep->get_behaviour_var('_rawfraction'))->get_feedback_class();
     }
     $gradingdetails = get_string('gradingdetails', 'qbehaviour_adaptive', $mark);
     $gradingdetails .= $this->penalty_info($qa, $mark, $options);
     $output = '';
     $output .= html_writer::tag('div', get_string($class, 'question'), array('class' => 'correctness ' . $class));
     $output .= html_writer::tag('div', $gradingdetails, array('class' => 'gradingdetails'));
     return $output;
 }
Esempio n. 2
0
 public function grade_response(array $response)
 {
     $fraction = 0;
     list($numright, $total) = $this->get_num_parts_right($response);
     $numwrong = $this->get_num_selected_choices($response) - $numright;
     $numcorrect = $this->get_num_correct_choices();
     if ($numwrong == 0 && $numcorrect == $numright) {
         $fraction = 1;
     }
     $state = question_state::graded_state_for_fraction($fraction);
     return array($fraction, $state);
 }
Esempio n. 3
0
 public function correct_response(question_attempt $qa)
 {
     $result = "";
     $question = $qa->get_question();
     if ($question->shownumcorrect) {
         foreach ($question->get_order($qa) as $ans_number => $ans_id) {
             $answer = $question->answers[$ans_id];
             if (question_state::graded_state_for_fraction($answer->fraction) == question_state::$gradedright) {
                 $result = get_string('correctansweris', 'qtype_multichoice', qtype_omeromultichoice_base_renderer::number_answer($ans_number, $question->answernumbering));
             }
         }
     }
     return $result;
 }
Esempio n. 4
0
 public function get_state_string($showcorrectness)
 {
     $laststep = $this->qa->get_last_step();
     if ($laststep->has_behaviour_var('_try')) {
         $state = question_state::graded_state_for_fraction($laststep->get_behaviour_var('_rawfraction'));
         return $state->default_string(true);
     }
     $state = $this->qa->get_state();
     if ($state == question_state::$todo) {
         return get_string('notcomplete', 'qbehaviour_adaptive');
     } else {
         return parent::get_state_string($showcorrectness);
     }
 }
Esempio n. 5
0
 /**
  * Find the corresponding choice id of the first correct answer of a shortanswer question.
  * choice is added to the randomsamatch question if it doesn't already exist.
  * @param object $wrappedquestion short answer question.
  * @return int correct choice id.
  */
 public function find_right_answer($wrappedquestion)
 {
     // We only take into account *one* (the first) correct answer.
     while ($answer = array_shift($wrappedquestion->answers)) {
         if (!question_state::graded_state_for_fraction($answer->fraction)->is_incorrect()) {
             // Store this answer as a choice, only if this is a new one.
             $key = array_search($answer->answer, $this->choices);
             if ($key === false) {
                 $key = $answer->id;
                 $this->choices[$key] = $answer->answer;
             }
             return $key;
         }
     }
     // We should never get there.
     throw new coding_exception('shortanswerquestionwithoutrightanswer', $wrappedquestion->id);
 }
Esempio n. 6
0
 public function get_correct_answer() {
     foreach ($this->question->get_answers() as $answer) {
         $state = question_state::graded_state_for_fraction($answer->fraction);
         if ($state == question_state::$gradedright) {
             return $answer;
         }
     }
     return null;
 }
 /**
  * Create a question_attempt_step from records loaded from the database.
  * @param Iterator $records Raw records loaded from the database.
  * @param int $stepid The id of the records to extract.
  * @param string $qtype The question type of which this is an attempt.
  *      If not given, each record must include a qtype field.
  * @return question_attempt_step The newly constructed question_attempt_step.
  */
 public static function load_from_records($records, $attemptstepid, $qtype = null)
 {
     $currentrec = $records->current();
     while ($currentrec->attemptstepid != $attemptstepid) {
         $records->next();
         if (!$records->valid()) {
             throw new coding_exception('Question attempt step ' . $attemptstepid . ' not found in the database.');
         }
         $currentrec = $records->current();
     }
     $record = $currentrec;
     $contextid = null;
     $data = array();
     while ($currentrec && $currentrec->attemptstepid == $attemptstepid) {
         if (!is_null($currentrec->name)) {
             $data[$currentrec->name] = $currentrec->value;
         }
         $records->next();
         if ($records->valid()) {
             $currentrec = $records->current();
         } else {
             $currentrec = false;
         }
     }
     $step = new question_attempt_step_read_only($data, $record->timecreated, $record->userid);
     $step->state = question_state::get($record->state);
     $step->id = $record->attemptstepid;
     if (!is_null($record->fraction)) {
         $step->fraction = $record->fraction + 0;
     }
     // This next chunk of code requires getting $contextid and $qtype here.
     // Somehow, we need to get that information to this point by modifying
     // all the paths by which this method can be called.
     // Can we only return files when it's possible? Should there be some kind of warning?
     if (is_null($qtype)) {
         $qtype = $record->qtype;
     }
     foreach (question_bank::get_qtype($qtype)->response_file_areas() as $area) {
         if (empty($step->data[$area])) {
             continue;
         }
         $step->data[$area] = new question_file_loader($step, $area, $step->data[$area], $record->contextid);
     }
     return $step;
 }
Esempio n. 8
0
 protected function get_num_correct_choices($questiondata)
 {
     $numright = 0;
     foreach ($questiondata->options->answers as $answer) {
         if (!question_state::graded_state_for_fraction($answer->fraction)->is_incorrect()) {
             $numright += 1;
         }
     }
     return $numright;
 }
Esempio n. 9
0
 /**
  * Call local or remote execute function. Evaluation of junit output is done. Grade is calculated and feedback
  * generated.
  *
  * @param array $response the response of the student
  * @return array $fraction fraction of the grade. If the max grade is 10 then fraction can be for example 2 (10/5 =
  *         2 indicating that from 10 points the student achieved 5).
  */
 public function grade_response(array $response)
 {
     global $CFG, $DB;
     if ($this->questionattemptid === null) {
         // we need the attempt id
         throw new Exception('qtype_javaunittest: grade_response, no questionattemptid');
     }
     $fraction = 0;
     $feedback = '';
     $cfg_plugin = get_config('qtype_javaunittest');
     if (empty($cfg_plugin->remoteserver)) {
         $ret = $this->local_execute($response);
     } else {
         $ret = $this->remote_execute($response);
     }
     if ($ret['error']) {
         if ($ret['errortype'] == 'COMPILE_STUDENT_ERROR') {
             $feedback = get_string('CE', 'qtype_javaunittest') . '<br><pre>' . htmlspecialchars($ret['compileroutput']) . '</pre>';
         } else {
             if ($ret['errortype'] == 'COMPILE_TESTFILE_ERROR') {
                 $feedback = get_string('JE', 'qtype_javaunittest');
             } else {
                 if ($ret['errortype'] == 'TIMEOUT_RUNNING') {
                     $feedback = get_string('TO', 'qtype_javaunittest');
                 } else {
                     if ($ret['errortype'] == 'REMOTE_SERVER_ERROR') {
                         $feedback = htmlspecialchars('REMOTE_SERVER_ERROR: ' . $ret['message']);
                     }
                 }
             }
         }
     } else {
         // the JUnit-execution-output returns always a String in the first line
         // e.g. "...F",
         // which means that 1 out of 3 test cases didn't pass the JUnit test
         // In the second line it says "Time ..."
         $output = $ret['junitoutput'];
         $junitstart = strrpos($output, 'JUnit version');
         $matches = array();
         $found = preg_match('@JUnit version [\\d\\.]*\\n([\\.EF]+)\\n@', $output, $matches, 0, $junitstart);
         if (!$found) {
             $feedback = get_string('JE', 'qtype_javaunittest');
         } else {
             // count failures and errors
             $numtests = substr_count($matches[1], '.');
             $numfailures = substr_count($matches[1], 'F');
             $numerrors = substr_count($matches[1], 'E');
             $totalerrors = $numfailures + $numerrors;
             $fraction = 1 - round($totalerrors / $numtests, 2);
             // generate feedback
             if ($this->feedbacklevel >= FEEDBACK_ONLY_TIMES) {
                 $feedback = get_string('compiling', 'qtype_javaunittest', round($ret['compiletime'], 1));
                 $feedback .= "<br>\n";
                 $feedback .= get_string('running', 'qtype_javaunittest', round($ret['testruntime'], 1));
                 $feedback .= "<br>\n";
                 $feedback .= "<br>\n";
             }
             if ($this->feedbacklevel >= FEEDBACK_TIMES_COUNT_OF_TESTS) {
                 $feedback .= "Tests: " . $numtests . "<br>\n";
                 $feedback .= "Failures: " . $numfailures . "<br>\n";
                 $feedback .= "Errors: " . $numerrors . "<br>\n";
                 $feedback .= "<br>\n";
                 $feedback .= "<br>\n";
             }
             if ($this->feedbacklevel == FEEDBACK_ALL_EXCEPT_STACKTRACE) {
                 $matches = array();
                 $found = preg_match('@(.*)There (were|was) (\\d*) failure(s?):\\n@s', $output, $matches);
                 if ($found) {
                     $feedback .= '<pre>' . htmlspecialchars($matches[1]) . '</pre>';
                     $feedback .= "<br>\n";
                 } else {
                     $feedback .= '<pre>' . htmlspecialchars($output) . '</pre>';
                     $feedback .= "<br>\n";
                 }
                 $feedback .= "<br>\n";
             }
             // search for common throwables, ordered primary by package, secundary by alphabet
             if (strpos($output, 'java.io.IOException') !== false) {
                 $feedback .= get_string('ioexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.io.FileNotFoundException') !== false) {
                 $feedback .= get_string('filenotfoundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.ArrayIndexOutOfBoundsException') !== false) {
                 $feedback .= get_string('arrayindexoutofboundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.ClassCastException') !== false) {
                 $feedback .= get_string('classcastexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.NegativeArraySizeException') !== false) {
                 $feedback .= get_string('negativearraysizeexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.NullPointerException') !== false) {
                 $feedback .= get_string('nullpointerexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.OutOfMemoryError') !== false) {
                 $feedback .= get_string('outofmemoryerror', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.StackOverflowError') !== false) {
                 $feedback .= get_string('stackoverflowerror', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.StringIndexOutOfBoundsException') !== false) {
                 $feedback .= get_string('stringindexoutofboundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.nio.BufferOverflowException') !== false) {
                 $feedback .= get_string('bufferoverflowexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.nio.BufferUnderflowException') !== false) {
                 $feedback .= get_string('bufferunderflowexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.security.AccessControlException') !== false) {
                 $feedback .= get_string('accesscontrolexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             // append feedback phrase (wrong / [partially] corrent answer phrase)
             if ($numtests > 0 && $totalerrors == 0) {
                 $feedback .= get_string('CA', 'qtype_javaunittest');
                 $feedback .= "<br>\n";
             } else {
                 if ($numtests > 0 && $numtests == $totalerrors) {
                     $feedback .= get_string('WA', 'qtype_javaunittest');
                     $feedback .= "<br>\n";
                 } else {
                     if ($numtests > 0 && $totalerrors != 0) {
                         $feedback .= get_string('PCA', 'qtype_javaunittest');
                         $feedback .= "<br>\n";
                     }
                 }
             }
         }
     }
     // save feedback
     $cur_feedback = $DB->get_record('qtype_javaunittest_feedback', array('questionattemptid' => $this->questionattemptid));
     $db_feedback = new stdClass();
     $db_feedback->questionattemptid = $this->questionattemptid;
     $db_feedback->feedback = $feedback;
     if ($cur_feedback) {
         $db_feedback->id = $cur_feedback->id;
         $DB->update_record('qtype_javaunittest_feedback', $db_feedback);
     } else {
         $DB->insert_record('qtype_javaunittest_feedback', $db_feedback);
     }
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 10
0
 public function grade_response(array $response)
 {
     $this->update_current_response($response);
     $countcorrect = 0;
     $countanswers = 0;
     $correctresponse = $this->correctresponse;
     $currentresponse = $this->currentresponse;
     foreach ($currentresponse as $position => $answerid) {
         if ($correctresponse[$position] == $answerid) {
             $countcorrect++;
         }
         $countanswers++;
     }
     if ($countanswers == 0) {
         $fraction = 0;
     } else {
         $fraction = $countcorrect / $countanswers;
     }
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 11
0
 /**
  * Call local or remote execute function. Evaluation of junit output is done. Grade is calculated and feedback
  * generated.
  *
  * @param array $response the response of the student
  * @return array $fraction fraction of the grade. If the max grade is 10 then fraction can be for example 2 (10/5 =
  *         2 indicating that from 10 points the student achieved 5).
  */
 public function grade_response(array $response)
 {
     global $CFG, $DB;
     if ($this->questionattemptid === null) {
         // we need the attempt id
         throw new Exception('qtype_javaunittest: grade_response, no questionattemptid');
     }
     $weight_style;
     if ($this->auditlevel == AUDIT_VALUE_10) {
         $weight_style = 0.1;
     } else {
         if ($this->auditlevel == AUDIT_VALUE_20) {
             $weight_style = 0.2;
         } else {
             if ($this->auditlevel == AUDIT_VALUE_30) {
                 $weight_style = 0.3;
             } else {
                 if ($this->auditlevel == AUDIT_VALUE_40) {
                     $weight_style = 0.4;
                 } else {
                     if ($this->auditlevel == AUDIT_VALUE_50) {
                         $weight_style = 0.5;
                     } else {
                         if ($this->auditlevel == AUDIT_VALUE_60) {
                             $weight_style = 0.6;
                         } else {
                             if ($this->auditlevel == AUDIT_VALUE_70) {
                                 $weight_style = 0.7;
                             } else {
                                 if ($this->auditlevel == AUDIT_VALUE_80) {
                                     $weight_style = 0.8;
                                 } else {
                                     if ($this->auditlevel == AUDIT_VALUE_90) {
                                         $weight_style = 0.9;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     /*else{
     	$weight_style = 1.0
     	}*/
     $fraction = 0;
     $fraction_code = 0;
     #$weight_style = 0.3;
     #$weight_style = $auditlevel;
     $weight_unittests = 1.0 - $weight_style;
     $num_errors_style = 0;
     $feedback = '';
     $cfg_plugin = get_config('qtype_javaunittest');
     if (empty($cfg_plugin->remoteserver)) {
         $ret = $this->local_execute($response);
     } else {
         $ret = $this->remote_execute($response);
     }
     $num_errors_style = substr_count($ret['auditoutput'], '.java:');
     $max_errors_style = 6;
     if ($num_errors_style < 0) {
         $num_errors_style = 0;
     }
     if ($num_errors_style > $max_errors_style) {
         $num_errors_style = $max_errors_style;
     }
     $fraction_style = ($max_errors_style - $num_errors_style) * 1.0 / $max_errors_style;
     if ($ret['error']) {
         if ($ret['errortype'] == 'COMPILE_STUDENT_ERROR') {
             $feedback = get_string('CE', 'qtype_javaunittest') . '<br><pre>' . htmlspecialchars($ret['compileroutput']) . '</pre>';
         } else {
             if ($ret['errortype'] == 'COMPILE_TESTFILE_ERROR') {
                 $feedback = get_string('JE', 'qtype_javaunittest');
                 $output = $ret['compileroutput'];
                 $feedback .= '<br/>';
                 $feedback .= '<div style="border:1px solid #000;">';
                 $feedback .= '<b><font color="red">Error in Unit Test Definition</font></b>';
                 $feedback .= '</div><br/>';
                 $feedback .= '<font color="#0000A0"><b>Details of the execution:</b></font><br/>';
                 $feedback .= '<pre>' . $output . '</pre>';
                 $feedback .= '<br/>';
             } else {
                 if ($ret['errortype'] == 'TIMEOUT_RUNNING') {
                     $feedback = get_string('TO', 'qtype_javaunittest');
                 } else {
                     if ($ret['errortype'] == 'REMOTE_SERVER_ERROR') {
                         $feedback = htmlspecialchars('REMOTE_SERVER_ERROR: ' . $ret['message']);
                     }
                 }
             }
         }
     } else {
         // the JUnit-execution-output returns always a String in the first line
         // e.g. "...F",
         // which means that 1 out of 3 test cases didn't pass the JUnit test
         // In the second line it says "Time ..."
         $output = $ret['junitoutput'];
         $junitstart = strrpos($output, 'JUnit version');
         $matches = array();
         $found = preg_match('@JUnit version [\\d\\.]*\\n([\\.EF]+)\\n@', $output, $matches, 0, $junitstart);
         if (!$found) {
             $feedback = get_string('JE', 'qtype_javaunittest');
             $feedback .= '<br/>';
             $feedback .= '<div style="border:1px solid #000;">';
             $feedback .= '<b><font color="red">Error in Unit Test Definition</font></b>';
             $feedback .= '</div><br/>';
             $feedback .= '<font color="#0000A0"><b>Details of the execution:</b></font><br/>';
             $feedback .= '<pre>' . $ret['compileroutput'] . '</pre>';
             $feedback .= '<br/>';
         } else {
             // count failures and errors
             $numtests = substr_count($matches[1], '.');
             $numfailures = substr_count($matches[1], 'F');
             $numerrors = substr_count($matches[1], 'E');
             $totalerrors = $numfailures + $numerrors;
             $fraction_code = 1 - round($totalerrors / $numtests, 2);
             $fraction = $fraction_code * $weight_unittests + $fraction_style * $weight_style;
             // generate feedback
             if ($this->feedbacklevel >= FEEDBACK_ONLY_TIMES) {
                 $feedback = get_string('compiling', 'qtype_javaunittest', round($ret['compiletime'], 1));
                 $feedback .= "<br>\n";
                 $feedback .= get_string('running', 'qtype_javaunittest', round($ret['testruntime'], 1));
                 $feedback .= "<br>\n";
             }
             if ($this->feedbacklevel >= FEEDBACK_TIMES_COUNT_OF_TESTS) {
                 #$feedback .= "Tests: " . $numtests . "<br>\n";
                 #$feedback .= "Failures: " . $numfailures . "<br>\n";
                 #$feedback .= "Errors: " . $numerrors . "<br>\n";
                 $feedback .= "<br>\n";
             }
             if ($this->feedbacklevel == FEEDBACK_ALL_EXCEPT_STACKTRACE) {
                 $matches = array();
                 $found = preg_match('@(.*)There (were|was) (\\d*) failure(s?):\\n@s', $output, $matches);
                 if ($found) {
                     $feedback .= '<pre>' . htmlspecialchars($matches[1]) . '</pre>';
                     $feedback .= "<br>\n";
                 } else {
                     $feedback .= '<pre>' . htmlspecialchars($output) . '</pre>';
                     $feedback .= "<br>\n";
                 }
             }
             if ($this->feedbacklevel == FEEDBACK_ALL) {
                 $feedback .= '<font color="#5F04B4"><b>';
                 if ($numtests > 0 && $totalerrors == 0 && $num_errors_style == 0) {
                     $feedback .= get_string('CA', 'qtype_javaunittest');
                 } else {
                     if ($numtests > 0 && ($totalerrors > 0 || $num_errors_style > 0)) {
                         $feedback .= get_string('PCA', 'qtype_javaunittest');
                     } else {
                         if ($numtests > 0 && ($numtests >= $totalerrors && $num_errors_style >= $max_errors_style)) {
                             $feedback .= get_string('WA', 'qtype_javaunittest');
                         }
                     }
                 }
                 $feedback .= "</b></font>\n";
                 $feedback .= "<br>\n";
                 $feedback .= '<font color="#0000A0">Global grade for the current question: <b>' . $fraction * 100 . '&#37; / ' . 100 . '&#37;</b></font><br/><br/>';
                 $feedback .= "<br>\n";
                 $outtext = preg_replace('/at(.*)\\)\\n/', '', $output);
                 $outtext = htmlspecialchars($outtext);
                 $outtext = preg_replace('/junit(.*)\\n/', '<br/><b>junit$1</b><br/>', $outtext);
                 $output_audit = preg_replace('/at(.*)\\)\\n/', '', $output);
                 $output_audit = htmlspecialchars($ret['auditoutput']);
                 #$cwd = getcwd();
                 #$feedback .= 'cwd=' .  getcwd() . '<br/>';
                 #$feedback .= 'dirroot=' .  $CFG->dirroot  . '<br/>';
                 #$feedback .= 'wwwroot=' .  $CFG->wwwroot  . '<br/>';
                 $feedback .= '<div style="border:1px solid #000;">';
                 $feedback .= '<b><font color="blue">Results of Code Audit</font></b>';
                 $feedback .= '</div><br/>';
                 $feedback .= '<font color="#0000A0">Value of Code Audit in question grade: <b>' . $weight_style * 100 . '&#37;</b></font><br/>';
                 $feedback .= '<font color="#0000A0">The first <b>' . $max_errors_style . '</b> errors give bad points</font><br/>';
                 $feedback .= '<font color="#0000A0">Number of errors made by the student: <b>' . $num_errors_style . '</b></font><br/>';
                 $feedback .= '<font color="#0000A0">Grade for section Code Audit: <b>' . $fraction_style * $weight_style * 100 . '&#37; / ' . $weight_style * 100 . '&#37;</b></font><br/><br/>';
                 $feedback .= '<font color="#0000A0"><b>Details of audit hereafter:</b></font><br/>';
                 $feedback .= '<pre>' . $output_audit . '</pre>';
                 $feedback .= '<br/>';
                 $feedback .= '<div style="border:1px solid #000;">';
                 $feedback .= '<b><font color="blue">Results of Unit Tests</font></b>';
                 $feedback .= '</div><br/>';
                 $feedback .= '<font color="#0000A0">Number of evaluated tests: <b>' . $numtests . '</b></font><br/>';
                 $feedback .= '<font color="#0000A0">Number of observed failures: <b>' . $numfailures . ' / ' . $numtests . '</b></font><br/>';
                 $feedback .= '<font color="#0000A0">Number of observed errors: <b>' . $numerrors . ' / ' . $numtests . '</b></font><br/>';
                 $feedback .= '<font color="#0000A0">Grade for section Unit Tests: <b>' . $fraction_code * $weight_unittests * 100 . '&#37; / ' . $weight_unittests * 100 . '&#37;</b></font><br/><br/>';
                 $feedback .= '<font color="#0000A0"><b>Details of unit tests hereafter:</b></font><br/>';
                 $feedback .= '<pre>' . $outtext . '</pre>';
                 $feedback .= "<br>\n";
             }
             // search for common throwables, by package, by alphabet
             if (strpos($output, 'java.io.IOException') !== false) {
                 $feedback .= get_string('ioexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.io.FileNotFoundException') !== false) {
                 $feedback .= get_string('filenotfoundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.ArrayIndexOutOfBoundsException') !== false) {
                 $feedback .= get_string('arrayindexoutofboundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.ClassCastException') !== false) {
                 $feedback .= get_string('classcastexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.NegativeArraySizeException') !== false) {
                 $feedback .= get_string('negativearraysizeexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.NullPointerException') !== false) {
                 $feedback .= get_string('nullpointerexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.OutOfMemoryError') !== false) {
                 $feedback .= get_string('outofmemoryerror', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.StackOverflowError') !== false) {
                 $feedback .= get_string('stackoverflowerror', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.lang.StringIndexOutOfBoundsException') !== false) {
                 $feedback .= get_string('stringindexoutofboundexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.nio.BufferOverflowException') !== false) {
                 $feedback .= get_string('bufferoverflowexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.nio.BufferUnderflowException') !== false) {
                 $feedback .= get_string('bufferunderflowexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             if (strpos($output, 'java.security.AccessControlException') !== false) {
                 $feedback .= get_string('accesscontrolexception', 'qtype_javaunittest');
                 $feedback .= "<br>\n<br>\n";
             }
             // append feedback phrase (wrong / [partially] corrent answer phrase)
             if ($numtests > 0 && $totalerrors == 0 && $num_errors_style == 0) {
                 $feedback .= get_string('CA', 'qtype_javaunittest');
             } else {
                 if ($numtests > 0 && ($totalerrors != 0 || $num_errors_style != 0)) {
                     $feedback .= get_string('PCA', 'qtype_javaunittest');
                 } else {
                     if ($numtest > 0 && ($numtests >= $totalerrors && $num_errors_style >= $max_errors_style)) {
                         $feedback .= get_string('WA', 'qtype_javaunittest');
                     }
                 }
             }
             $feedback .= "<br>\n";
         }
     }
     // save feedback
     $cur_feedback = $DB->get_record('qtype_javaunittest_feedback', array('questionattemptid' => $this->questionattemptid));
     $db_feedback = new stdClass();
     $db_feedback->questionattemptid = $this->questionattemptid;
     $db_feedback->feedback = $feedback;
     if ($cur_feedback) {
         $db_feedback->id = $cur_feedback->id;
         $DB->update_record('qtype_javaunittest_feedback', $db_feedback);
     } else {
         $DB->insert_record('qtype_javaunittest_feedback', $db_feedback);
     }
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 12
0
    /**
     * Return an appropriate icon (green tick, red cross, etc.) for a grade.
     * @param float $fraction grade on a scale 0..1.
     * @return string html fragment.
     */
    protected function icon_for_fraction($fraction) {
        global $OUTPUT;

        $feedbackclass = question_state::graded_state_for_fraction($fraction)->get_feedback_class();
        return $OUTPUT->pix_icon('i/grade_' . $feedbackclass, get_string($feedbackclass, 'question'),
                'moodle', array('class' => 'icon'));
    }
Esempio n. 13
0
 public function grade_response(array $response)
 {
     $response = $this->discard_duplicates($response);
     list($right, $total) = $this->get_num_parts_right($response);
     $this->fraction = $right / $total;
     $grade = array($this->fraction, question_state::graded_state_for_fraction($this->fraction));
     return $grade;
 }
Esempio n. 14
0
    /**
     * Return an appropriate icon (green tick, red cross, etc.) for a grade.
     * @param float $fraction grade on a scale 0..1.
     * @return string html fragment.
     */
    protected function icon_for_fraction($fraction) {
        global $OUTPUT;

        $state = question_state::graded_state_for_fraction($fraction);
        if ($state == question_state::$gradedright) {
            $icon = 'i/tick_green_big';
        } else if ($state == question_state::$gradedpartial) {
            $icon = 'i/tick_amber_big';
        } else {
            $icon = 'i/cross_red_big';
        }

        return $OUTPUT->pix_icon($icon, get_string($state->get_feedback_class(), 'question'),
                'moodle', array('class' => 'icon'));
    }
Esempio n. 15
0
    /**
     * Render the feedback pop-up contents.
     *
     * @param question_graded_automatically $subq the subquestion.
     * @param float $fraction the mark the student got. null if this subq was not answered.
     * @param string $feedbacktext the feedback text, already processed with format_text etc.
     * @param string $rightanswer the right answer, already processed with format_text etc.
     * @param question_display_options $options the display options.
     * @return string the HTML for the feedback popup.
     */
    protected function feedback_popup(question_graded_automatically $subq,
            $fraction, $feedbacktext, $rightanswer, question_display_options $options) {

        if (!$options->feedback) {
            return '';
        }

        $feedback = array();
        if ($options->correctness) {
            if (is_null($fraction)) {
                $state = question_state::$gaveup;
            } else {
                $state = question_state::graded_state_for_fraction($fraction);
            }
            $feedback[] = $state->default_string(true);
        }

        if ($options->rightanswer) {
            $feedback[] = get_string('correctansweris', 'qtype_shortanswer', $rightanswer);
        }

        $subfraction = '';
        if ($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[] = get_string('markoutofmax', 'question', $a);
        }

        return html_writer::tag('span', implode('<br />', $feedback),
                array('class' => 'feedbackspan accesshide'));
    }
Esempio n. 16
0
 public function test_graded_state_for_fraction()
 {
     $this->assertEquals(question_state::$gradedwrong, question_state::graded_state_for_fraction(-1));
     $this->assertEquals(question_state::$gradedwrong, question_state::graded_state_for_fraction(0));
     $this->assertEquals(question_state::$gradedpartial, question_state::graded_state_for_fraction(1.0E-6));
     $this->assertEquals(question_state::$gradedpartial, question_state::graded_state_for_fraction(0.999999));
     $this->assertEquals(question_state::$gradedright, question_state::graded_state_for_fraction(1));
 }
 /**
  * @param string $colname the name of the column.
  * @param object $attempt the row of data - see the SQL in display() in
  * mod/quiz/report/overview/report.php to see what fields are present,
  * and what they are called.
  * @return string the contents of the cell.
  */
 public function other_cols($colname, $attempt)
 {
     if (!preg_match('/^qsgrade(\\d+)$/', $colname, $matches)) {
         return null;
     }
     $slot = $matches[1];
     $question = $this->questions[$slot];
     if (!isset($this->lateststeps[$attempt->usageid][$slot])) {
         return '-';
     }
     $stepdata = $this->lateststeps[$attempt->usageid][$slot];
     $state = question_state::get($stepdata->state);
     if ($question->maxmark == 0) {
         $grade = '-';
     } else {
         if (is_null($stepdata->fraction)) {
             if ($state == question_state::$needsgrading) {
                 $grade = get_string('requiresgrading', 'question');
             } else {
                 $grade = '-';
             }
         } else {
             $grade = quiz_rescale_grade($stepdata->fraction * $question->maxmark, $this->quiz, 'question');
         }
     }
     if ($this->is_downloading()) {
         return $grade;
     }
     if (isset($this->regradedqs[$attempt->usageid][$slot])) {
         $gradefromdb = $grade;
         $newgrade = quiz_rescale_grade($this->regradedqs[$attempt->usageid][$slot]->newfraction * $question->maxmark, $this->quiz, 'question');
         $oldgrade = quiz_rescale_grade($this->regradedqs[$attempt->usageid][$slot]->oldfraction * $question->maxmark, $this->quiz, 'question');
         $grade = html_writer::tag('del', $oldgrade) . '/' . html_writer::empty_tag('br') . $newgrade;
     }
     return $this->make_review_link($grade, $attempt, $slot);
 }
Esempio n. 18
0
 protected function get_contains_subq_status(question_state $state)
 {
     return new question_pattern_expectation('~' . preg_quote($state->default_string(true), '~') . '<br />~');
 }
Esempio n. 19
0
 public function grade_response(array $response)
 {
     if ($this->has_separate_unit_field()) {
         $selectedunit = $response['unit'];
     } else {
         $selectedunit = null;
     }
     list($value, $unit, $multiplier) = $this->ap->apply_units($response['answer'], $selectedunit);
     $answer = $this->get_matching_answer($value, $multiplier);
     if (!$answer) {
         return array(0, question_state::$gradedwrong);
     }
     $fraction = $this->apply_unit_penalty($answer->fraction, $answer->unitisright);
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 20
0
 public function grade_response(array $response)
 {
     $fraction = 0;
     foreach ($this->order as $key => $ansid) {
         if (!empty($response[$this->field($key)])) {
             $fraction += $this->answers[$ansid]->fraction;
         }
     }
     $fraction = min(max(0, $fraction), 1.0);
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 21
0
 /**
  * Get the SQL needed to test that question_attempt_steps.state is in a
  * state corresponding to $summarystate.
  * @param string $summarystate one of
  * inprogress, needsgrading, manuallygraded or autograded
  * @param bool $equal if false, do a NOT IN test. Default true.
  * @return string SQL fragment.
  */
 public function in_summary_state_test($summarystate, $equal = true, $prefix = 'summarystates')
 {
     $states = question_state::get_all_for_summary_state($summarystate);
     return $this->db->get_in_or_equal(array_map('strval', $states), SQL_PARAMS_NAMED, $prefix, $equal);
 }
Esempio n. 22
0
 public function grade_response(array $response)
 {
     list($right, $total) = $this->get_num_parts_right($response);
     $fraction = $right / $total;
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
 /**
  * Get the current mark details for a particular part.
  * @param string $index the part index.
  * @return qbehaviour_adaptivemultipart_mark_details the marks information.
  */
 public function get_part_mark_details($index)
 {
     $step = $this->qa->get_last_step_with_behaviour_var('_tries_' . $index);
     if (!$step->has_behaviour_var('_tries_' . $index)) {
         return new qbehaviour_adaptivemultipart_mark_details(question_state::$todo);
     }
     $weights = $this->question->get_parts_and_weights();
     $state = question_state::graded_state_for_fraction($step->get_behaviour_var('_rawfraction_' . $index));
     $details = new qbehaviour_adaptivemultipart_mark_details($state);
     $details->maxmark = $weights[$index] * $this->qa->get_max_mark();
     $details->actualmark = $step->get_behaviour_var('_fraction_' . $index) * $details->maxmark;
     $details->rawmark = $step->get_behaviour_var('_rawfraction_' . $index) * $details->maxmark;
     $details->currentpenalty = $step->get_behaviour_var('_curpenalty_' . $index) * $details->maxmark;
     $details->totalpenalty = $step->get_behaviour_var('_penalty_' . $index) * $details->maxmark;
     $details->improvable = !$state->is_correct();
     return $details;
 }
Esempio n. 24
0
 public function grade_response(array $response)
 {
     $fraction = 0;
     foreach ($this->prts as $index => $prt) {
         $results = $this->get_prt_result($index, $response, true);
         $fraction += $results->fraction;
     }
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
 public function grade_response(array $response)
 {
     if ($this->rightanswer == true && $response['answer'] == true) {
         $fraction = 1;
     } else {
         if ($this->rightanswer == false && $response['answer'] == false) {
             $fraction = 1;
         } else {
             $fraction = 0;
         }
     }
     return array($fraction, question_state::graded_state_for_fraction($fraction));
 }
Esempio n. 26
0
    /**
     * Output the content of the subquestion.
     *
     * @param question_attempt $qa
     * @param question_display_options $options
     * @param int $index
     * @param question_graded_automatically $subq
     * @return string
     */
    public function subquestion(question_attempt $qa, question_display_options $options,
                                $index, question_graded_automatically $subq) {

        if (!$subq instanceof qtype_multichoice_multi_question) {
            throw new coding_exception('Expecting subquestion of type qtype_multichoice_multi_question');
        }

        $fieldprefix = 'sub' . $index . '_';
        $fieldname = $fieldprefix . 'choice';

        // Extract the responses that related to this question + strip off the prefix.
        $fieldprefixlen = strlen($fieldprefix);
        $response = [];
        foreach ($qa->get_last_qt_data() as $name => $val) {
            if (substr($name, 0, $fieldprefixlen) == $fieldprefix) {
                $name = substr($name, $fieldprefixlen);
                $response[$name] = $val;
            }
        }

        $basename = $qa->get_qt_field_name($fieldname);
        $inputattributes = array(
            'type' => 'checkbox',
            'value' => 1,
        );
        if ($options->readonly) {
            $inputattributes['disabled'] = 'disabled';
        }

        $result = $this->all_choices_wrapper_start();

        // Calculate the total score (as we need to know if choices should be marked as 'correct' or 'partial').
        $fraction = 0;
        foreach ($subq->get_order($qa) as $value => $ansid) {
            $ans = $subq->answers[$ansid];
            if ($subq->is_choice_selected($response, $value)) {
                $fraction += $ans->fraction;
            }
        }
        // Display 'correct' answers as correct, if we are at 100%, otherwise mark them as 'partial'.
        $answerfraction = ($fraction > 0.999) ? 1.0 : 0.5;

        foreach ($subq->get_order($qa) as $value => $ansid) {
            $ans = $subq->answers[$ansid];

            $name = $basename.$value;
            $inputattributes['name'] = $name;
            $inputattributes['id'] = $name;

            $isselected = $subq->is_choice_selected($response, $value);
            if ($isselected) {
                $inputattributes['checked'] = 'checked';
            } else {
                unset($inputattributes['checked']);
            }

            $class = 'r' . ($value % 2);
            if ($options->correctness && $isselected) {
                $thisfrac = ($ans->fraction > 0) ? $answerfraction : 0;
                $feedbackimg = $this->feedback_image($thisfrac);
                $class .= ' ' . $this->feedback_class($thisfrac);
            } 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) {
            $correct = [];
            foreach ($subq->answers as $ans) {
                if (question_state::graded_state_for_fraction($ans->fraction) != question_state::$gradedwrong) {
                    $correct[] = $subq->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ans->id);
                }
            }
            $correct = '<ul><li>'.implode('</li><li>', $correct).'</li></ul>';
            $feedback[] = get_string('correctansweris', 'qtype_multichoice', $correct);
        }

        $result .= html_writer::nonempty_tag('div', implode('<br />', $feedback), array('class' => 'outcome'));

        return $result;
    }
Esempio n. 27
0
    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 correct_response(question_attempt $qa)
 {
     $question = $qa->get_question();
     foreach ($question->answers as $ansid => $ans) {
         if (question_state::graded_state_for_fraction($ans->fraction) == question_state::$gradedright) {
             return get_string('correctansweris', 'qtype_multichoice', $question->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ansid));
         }
     }
     return '';
 }
Esempio n. 29
0
    public function correct_response(question_attempt $qa) {
        $question = $qa->get_question();

        // Put all correct answers (100% grade) into $right.
        $right = array();
        foreach ($question->answers as $ansid => $ans) {
            if (question_state::graded_state_for_fraction($ans->fraction) ==
                    question_state::$gradedright) {
                $right[] = $question->make_html_inline($question->format_text($ans->answer, $ans->answerformat,
                        $qa, 'question', 'answer', $ansid));
            }
        }
        return $this->correct_choices($right);
    }
Esempio n. 30
0
 public function correct_response(question_attempt $qa)
 {
     $right = array();
     $result = "";
     $question = $qa->get_question();
     if ($question->shownumcorrect) {
         foreach ($question->get_order($qa) as $ans_number => $ans_id) {
             $answer = $question->answers[$ans_id];
             if (question_state::graded_state_for_fraction($answer->fraction) == question_state::$gradedright) {
                 foreach (explode(",", $answer->answer) as $k => $v) {
                     array_push($right, '<i roi-shape-id="' . $v . '" class="glyphicon glyphicon-map-marker roi-shape-info"></i> ' . '[' . $v . "]");
                 }
             }
         }
         $result = get_string(count($right) == 1 ? 'single_correctansweris' : 'single_correctanswerare', 'qtype_omerointeractive') . implode(", ", $right);
     }
     return $result;
 }