/** Called to grade the output from a given testcase run when * the template was used to generate a program that does both the test * execution and the grading of the result. * Returns a single TestResult object. * Should not be called if the execution failed (syntax error, exception * etc). */ function grade_known_good(&$output, &$testcase) { $result = json_decode($output); if ($result === null || !isset($result->fraction) || !is_numeric($result->fraction)) { $errormessage = "Bad grading result from template:'" . $output . "'"; $outcome = new qtype_coderunner_test_result(qtype_coderunner_grader::tidy($testcase->testcode), $testcase->mark, false, 0.0, qtype_coderunner_grader::tidy($testcase->expected), $errormessage, qtype_coderunner_grader::tidy($testcase->stdin), qtype_coderunner_grader::tidy($testCase->extra)); } else { // First copy any missing fields from test case into result foreach (get_object_vars($testcase) as $key => $value) { if (!isset($result->{$key})) { $result->{$key} = $value; } } if (!isset($result->awarded)) { $result->awarded = $result->mark * $result->fraction; } if (!isset($result->got)) { $result->got = ''; } $result->iscorrect = abs($result->fraction - 1.0) < 1.0E-6; $outcome = new qtype_coderunner_test_result(qtype_coderunner_grader::tidy($result->testcode), $result->mark, $result->iscorrect, $result->awarded, qtype_coderunner_grader::tidy($result->expected), qtype_coderunner_grader::tidy($result->got), qtype_coderunner_grader::tidy($result->stdin), qtype_coderunner_grader::tidy($result->extra)); /* To accommodate generalised template graders that need to * have their own custom attributes, we also add any other result * attributes not already used into the TestResult object. */ foreach ((array) $result as $key => $value) { if (!isset($outcome->{$key})) { $outcome->{$key} = $value; } } } return $outcome; }
protected static function tidy($s) { if ($s === null) { return null; } else { $cleanS = qtype_coderunner_grader::clean($s); return qtype_coderunner_grader::snip($cleanS); } }
/** Called to grade the output generated by a student's code for * a given testcase. Returns a single TestResult object. * Should not be called if the execution failed (syntax error, exception * etc). */ function grade_known_good(&$output, &$testCase) { $regex = '/' . str_replace('/', '\\/', $testCase->expected) . '/ms'; $isCorrect = preg_match($regex, $output); $awardedMark = $isCorrect ? $testCase->mark : 0.0; if (isset($testCase->stdin)) { $resultStdin = qtype_coderunner_grader::tidy($testCase->stdin); } else { $resultStdin = null; } return new qtype_coderunner_test_result(qtype_coderunner_grader::tidy($testCase->testcode), $testCase->mark, $isCorrect, $awardedMark, qtype_coderunner_grader::snip($testCase->expected), qtype_coderunner_grader::snip($output), $resultStdin, qtype_coderunner_grader::tidy($testCase->extra)); }
/** This grader tests if the expected output matches the actual * output after removing all empty lines and trailing white space, * collapsing all sequences of space or tab characters to a single * space and converting all letters to lower case. [These changes * are of course applied to both expected and actual outputs.] * * As requested by Ulrich Dangel. */ function grade_known_good(&$output, &$testCase) { $cleanedOutput = qtype_coderunner_grader::clean($output); $cleanedExpected = qtype_coderunner_grader::clean($testCase->expected); $isCorrect = $this->reduce($cleanedOutput) == $this->reduce($cleanedExpected); $awardedMark = $isCorrect ? $testCase->mark : 0.0; if (isset($testCase->stdin)) { $resultStdin = qtype_coderunner_grader::tidy($testCase->stdin); } else { $resultStdin = null; } return new qtype_coderunner_test_result(qtype_coderunner_grader::tidy($testCase->testcode), $testCase->mark, $isCorrect, $awardedMark, qtype_coderunner_grader::snip($cleanedExpected), qtype_coderunner_grader::snip($cleanedOutput), $resultStdin, qtype_coderunner_grader::tidy($testCase->extra)); }
private function setup_grader() { global $CFG; $grader = $this->grader; if ($grader === null) { $this->grader = $grader = constants::DEFAULT_GRADER; } $filename = qtype_coderunner_grader::get_filename($grader); $graders = qtype_coderunner_grader::available_graders(); $graderclass = $graders[$grader]; require_once $CFG->dirroot . "/question/type/coderunner/grader/{$filename}"; $this->graderinstance = new $graderclass(); }