Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace qbank_statistics; 18 19 use core_question\statistics\questions\all_calculated_for_qubaid_condition; 20 use quiz; 21 use question_engine; 22 use quiz_attempt; 23 24 /** 25 * Tests for question statistics. 26 * 27 * @package qbank_statistics 28 * @copyright 2021 Catalyst IT Australia Pty Ltd 29 * @author Nathan Nguyen <nathannguyen@catalyst-au.net> 30 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 31 */ 32 class helper_test extends \advanced_testcase { 33 34 /** 35 * Test quizzes that contain a specified question. 36 * 37 * @covers ::get_all_places_where_questions_were_attempted 38 * @throws \coding_exception 39 * @throws \dml_exception 40 */ 41 public function test_get_all_places_where_questions_were_attempted(): void { 42 $this->resetAfterTest(); 43 $this->setAdminUser(); 44 45 $rcm = new \ReflectionMethod(helper::class, 'get_all_places_where_questions_were_attempted'); 46 $rcm->setAccessible(true); 47 48 // Create a course. 49 $course = $this->getDataGenerator()->create_course(); 50 51 // Create three quizzes. 52 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 53 $quiz1 = $quizgenerator->create_instance([ 54 'course' => $course->id, 55 'grade' => 100.0, 'sumgrades' => 2, 56 'layout' => '1,2,0' 57 ]); 58 $quiz1context = \context_module::instance($quiz1->cmid); 59 60 $quiz2 = $quizgenerator->create_instance([ 61 'course' => $course->id, 62 'grade' => 100.0, 'sumgrades' => 2, 63 'layout' => '1,2,0' 64 ]); 65 $quiz2context = \context_module::instance($quiz2->cmid); 66 67 $quiz3 = $quizgenerator->create_instance([ 68 'course' => $course->id, 69 'grade' => 100.0, 'sumgrades' => 2, 70 'layout' => '1,2,0' 71 ]); 72 $quiz3context = \context_module::instance($quiz3->cmid); 73 74 // Create questions. 75 /** @var \core_question_generator $questiongenerator */ 76 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 77 $cat = $questiongenerator->create_question_category(); 78 $question1 = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id)); 79 $question2 = $questiongenerator->create_question('numerical', null, array('category' => $cat->id)); 80 81 // Add question 1 to quiz 1 and make an attempt. 82 quiz_add_quiz_question($question1->id, $quiz1); 83 // Quiz 1 attempt. 84 $this->submit_quiz($quiz1, [1 => ['answer' => 'frog']]); 85 86 // Add questions 1 and 2 to quiz 2. 87 quiz_add_quiz_question($question1->id, $quiz2); 88 quiz_add_quiz_question($question2->id, $quiz2); 89 $this->submit_quiz($quiz2, [1 => ['answer' => 'frog'], 2 => ['answer' => 10]]); 90 91 // Checking quizzes that use question 1. 92 $q1places = $rcm->invoke(null, [$question1->id]); 93 $this->assertCount(2, $q1places); 94 $this->assertEquals((object) ['component' => 'mod_quiz', 'contextid' => $quiz1context->id], $q1places[0]); 95 $this->assertEquals((object) ['component' => 'mod_quiz', 'contextid' => $quiz2context->id], $q1places[1]); 96 97 // Checking quizzes that contain question 2. 98 $q2places = $rcm->invoke(null, [$question2->id]); 99 $this->assertCount(1, $q2places); 100 $this->assertEquals((object) ['component' => 'mod_quiz', 'contextid' => $quiz2context->id], $q2places[0]); 101 102 // Add a random question to quiz3. 103 quiz_add_random_questions($quiz3, 0, $cat->id, 1, false); 104 $this->submit_quiz($quiz3, [1 => ['answer' => 'willbewrong']]); 105 106 // Quiz 3 will now be in one of these arrays. 107 $q1places = $rcm->invoke(null, [$question1->id]); 108 $q2places = $rcm->invoke(null, [$question2->id]); 109 if (count($q1places) == 3) { 110 $newplace = end($q1places); 111 } else { 112 $newplace = end($q2places); 113 } 114 $this->assertEquals((object) ['component' => 'mod_quiz', 'contextid' => $quiz3context->id], $newplace); 115 } 116 117 /** 118 * Create 2 quizzes. 119 * 120 * @return array return 2 quizzes 121 * @throws \coding_exception 122 */ 123 private function prepare_quizzes(): array { 124 // Create a course. 125 $course = $this->getDataGenerator()->create_course(); 126 127 // Make 2 quizzes. 128 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 129 $layout = '1,2,0,3,4,0'; 130 $quiz1 = $quizgenerator->create_instance([ 131 'course' => $course->id, 132 'grade' => 100.0, 'sumgrades' => 2, 133 'layout' => $layout 134 ]); 135 136 $quiz2 = $quizgenerator->create_instance([ 137 'course' => $course->id, 138 'grade' => 100.0, 'sumgrades' => 2, 139 'layout' => $layout 140 ]); 141 142 /** @var \core_question_generator $questiongenerator */ 143 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 144 $cat = $questiongenerator->create_question_category(); 145 146 $page = 1; 147 $questions = []; 148 foreach (explode(',', $layout) as $slot) { 149 if ($slot == 0) { 150 $page += 1; 151 continue; 152 } 153 154 $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]); 155 $questions[$slot] = $question; 156 quiz_add_quiz_question($question->id, $quiz1, $page); 157 quiz_add_quiz_question($question->id, $quiz2, $page); 158 } 159 160 return [$quiz1, $quiz2, $questions]; 161 } 162 163 /** 164 * Submit quiz answers 165 * 166 * @param object $quiz 167 * @param array $answers 168 * @throws \moodle_exception 169 */ 170 private function submit_quiz(object $quiz, array $answers): void { 171 // Create user. 172 $user = $this->getDataGenerator()->create_user(); 173 // Create attempt. 174 $quizobj = quiz::create($quiz->id, $user->id); 175 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); 176 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); 177 $timenow = time(); 178 $attempt = quiz_create_attempt($quizobj, 1, null, $timenow, false, $user->id); 179 quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); 180 quiz_attempt_save_started($quizobj, $quba, $attempt); 181 // Submit attempt. 182 $attemptobj = quiz_attempt::create($attempt->id); 183 $attemptobj->process_submitted_actions($timenow, false, $answers); 184 $attemptobj->process_finish($timenow, false); 185 } 186 187 /** 188 * Generate attempt answers. 189 * 190 * @param array $correctanswerflags array of 1 or 0 191 * 1 : generate correct answer 192 * 0 : generate wrong answer 193 * 194 * @return array 195 */ 196 private function generate_attempt_answers(array $correctanswerflags): array { 197 $attempt = []; 198 for ($i = 1; $i <= 4; $i++) { 199 if (isset($correctanswerflags) && $correctanswerflags[$i - 1] == 1) { 200 // Correct answer. 201 $attempt[$i] = ['answer' => 'frog']; 202 } else { 203 $attempt[$i] = ['answer' => 'false']; 204 } 205 } 206 return $attempt; 207 } 208 209 /** 210 * 211 * Generate quizzes and submit answers. 212 * 213 * @param array $quiz1attempts quiz 1 attempts 214 * @param array $quiz2attempts quiz 2 attempts 215 * 216 * @return array 217 */ 218 private function prepare_and_submit_quizzes(array $quiz1attempts, array $quiz2attempts): array { 219 list($quiz1, $quiz2, $questions) = $this->prepare_quizzes(); 220 // Submit attempts of quiz1. 221 foreach ($quiz1attempts as $attempt) { 222 $this->submit_quiz($quiz1, $attempt); 223 } 224 // Submit attempts of quiz2. 225 foreach ($quiz2attempts as $attempt) { 226 $this->submit_quiz($quiz2, $attempt); 227 } 228 229 // Calculate the statistics. 230 $this->expectOutputRegex('~.*Calculations completed.*~'); 231 $statisticstask = new \quiz_statistics\task\recalculate(); 232 $statisticstask->execute(); 233 234 return [$quiz1, $quiz2, $questions]; 235 } 236 237 /** 238 * To use private helper::extract_item_value function. 239 * 240 * @param all_calculated_for_qubaid_condition $statistics the batch of statistics. 241 * @param int $questionid a question id. 242 * @param string $item ane of the field names in all_calculated_for_qubaid_condition, e.g. 'facility'. 243 * @return float|null the required value. 244 */ 245 private function extract_item_value(all_calculated_for_qubaid_condition $statistics, 246 int $questionid, string $item): ?float { 247 $rcm = new \ReflectionMethod(helper::class, 'extract_item_value'); 248 $rcm->setAccessible(true); 249 return $rcm->invoke(null, $statistics, $questionid, $item); 250 } 251 252 /** 253 * To use private helper::load_statistics_for_place function (with mod_quiz component). 254 * 255 * @param \context $context the context to load the statistics for. 256 * @return all_calculated_for_qubaid_condition|null question statistics. 257 */ 258 private function load_quiz_statistics_for_place(\context $context): ?all_calculated_for_qubaid_condition { 259 $rcm = new \ReflectionMethod(helper::class, 'load_statistics_for_place'); 260 $rcm->setAccessible(true); 261 return $rcm->invoke(null, 'mod_quiz', $context); 262 } 263 264 /** 265 * Data provider for {@see test_load_question_facility()}. 266 * 267 * @return \Generator 268 */ 269 public function load_question_facility_provider(): \Generator { 270 yield 'Facility case 1' => [ 271 'Quiz 1 attempts' => [ 272 $this->generate_attempt_answers([1, 0, 0, 0]), 273 ], 274 'Expected quiz 1 facilities' => ['100.00%', '0.00%', '0.00%', '0.00%'], 275 'Quiz 2 attempts' => [ 276 $this->generate_attempt_answers([1, 0, 0, 0]), 277 $this->generate_attempt_answers([1, 1, 0, 0]), 278 ], 279 'Expected quiz 2 facilities' => ['100.00%', '50.00%', '0.00%', '0.00%'], 280 'Expected average facilities' => ['100.00%', '25.00%', '0.00%', '0.00%'], 281 ]; 282 yield 'Facility case 2' => [ 283 'Quiz 1 attempts' => [ 284 $this->generate_attempt_answers([1, 0, 0, 0]), 285 $this->generate_attempt_answers([1, 1, 0, 0]), 286 $this->generate_attempt_answers([1, 1, 1, 0]), 287 ], 288 'Expected quiz 1 facilities' => ['100.00%', '66.67%', '33.33%', '0.00%'], 289 'Quiz 2 attempts' => [ 290 $this->generate_attempt_answers([1, 0, 0, 0]), 291 $this->generate_attempt_answers([1, 1, 0, 0]), 292 $this->generate_attempt_answers([1, 1, 1, 0]), 293 $this->generate_attempt_answers([1, 1, 1, 1]), 294 ], 295 'Expected quiz 2 facilities' => ['100.00%', '75.00%', '50.00%', '25.00%'], 296 'Expected average facilities' => ['100.00%', '70.83%', '41.67%', '12.50%'], 297 ]; 298 } 299 300 /** 301 * Test question facility 302 * 303 * @dataProvider load_question_facility_provider 304 * 305 * @param array $quiz1attempts quiz 1 attempts 306 * @param array $expectedquiz1facilities expected quiz 1 facilities 307 * @param array $quiz2attempts quiz 2 attempts 308 * @param array $expectedquiz2facilities expected quiz 2 facilities 309 * @param array $expectedaveragefacilities expected average facilities 310 */ 311 public function test_load_question_facility( 312 array $quiz1attempts, 313 array $expectedquiz1facilities, 314 array $quiz2attempts, 315 array $expectedquiz2facilities, 316 array $expectedaveragefacilities) 317 : void { 318 $this->resetAfterTest(); 319 320 list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts); 321 322 // Quiz 1 facilities. 323 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz1->cmid)); 324 $quiz1facility1 = $this->extract_item_value($stats, $questions[1]->id, 'facility'); 325 $quiz1facility2 = $this->extract_item_value($stats, $questions[2]->id, 'facility'); 326 $quiz1facility3 = $this->extract_item_value($stats, $questions[3]->id, 'facility'); 327 $quiz1facility4 = $this->extract_item_value($stats, $questions[4]->id, 'facility'); 328 329 $this->assertEquals($expectedquiz1facilities[0], helper::format_percentage($quiz1facility1)); 330 $this->assertEquals($expectedquiz1facilities[1], helper::format_percentage($quiz1facility2)); 331 $this->assertEquals($expectedquiz1facilities[2], helper::format_percentage($quiz1facility3)); 332 $this->assertEquals($expectedquiz1facilities[3], helper::format_percentage($quiz1facility4)); 333 334 // Quiz 2 facilities. 335 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz2->cmid)); 336 $quiz2facility1 = $this->extract_item_value($stats, $questions[1]->id, 'facility'); 337 $quiz2facility2 = $this->extract_item_value($stats, $questions[2]->id, 'facility'); 338 $quiz2facility3 = $this->extract_item_value($stats, $questions[3]->id, 'facility'); 339 $quiz2facility4 = $this->extract_item_value($stats, $questions[4]->id, 'facility'); 340 341 $this->assertEquals($expectedquiz2facilities[0], helper::format_percentage($quiz2facility1)); 342 $this->assertEquals($expectedquiz2facilities[1], helper::format_percentage($quiz2facility2)); 343 $this->assertEquals($expectedquiz2facilities[2], helper::format_percentage($quiz2facility3)); 344 $this->assertEquals($expectedquiz2facilities[3], helper::format_percentage($quiz2facility4)); 345 346 // Average question facilities. 347 $averagefacility1 = helper::calculate_average_question_facility($questions[1]->id); 348 $averagefacility2 = helper::calculate_average_question_facility($questions[2]->id); 349 $averagefacility3 = helper::calculate_average_question_facility($questions[3]->id); 350 $averagefacility4 = helper::calculate_average_question_facility($questions[4]->id); 351 352 $this->assertEquals($expectedaveragefacilities[0], helper::format_percentage($averagefacility1)); 353 $this->assertEquals($expectedaveragefacilities[1], helper::format_percentage($averagefacility2)); 354 $this->assertEquals($expectedaveragefacilities[2], helper::format_percentage($averagefacility3)); 355 $this->assertEquals($expectedaveragefacilities[3], helper::format_percentage($averagefacility4)); 356 } 357 358 /** 359 * Data provider for {@see test_load_question_discriminative_efficiency()}. 360 * @return \Generator 361 */ 362 public function load_question_discriminative_efficiency_provider(): \Generator { 363 yield 'Discriminative efficiency' => [ 364 'Quiz 1 attempts' => [ 365 $this->generate_attempt_answers([1, 0, 0, 0]), 366 $this->generate_attempt_answers([1, 1, 0, 0]), 367 $this->generate_attempt_answers([1, 0, 1, 0]), 368 $this->generate_attempt_answers([1, 1, 1, 1]), 369 ], 370 'Expected quiz 1 discriminative efficiency' => ['N/A', '33.33%', '33.33%', '100.00%'], 371 'Quiz 2 attempts' => [ 372 $this->generate_attempt_answers([1, 1, 1, 1]), 373 $this->generate_attempt_answers([0, 0, 0, 0]), 374 $this->generate_attempt_answers([1, 0, 0, 1]), 375 $this->generate_attempt_answers([0, 1, 1, 0]), 376 ], 377 'Expected quiz 2 discriminative efficiency' => ['50.00%', '50.00%', '50.00%', '50.00%'], 378 'Expected average discriminative efficiency' => ['50.00%', '41.67%', '41.67%', '75.00%'], 379 ]; 380 } 381 382 /** 383 * Test discriminative efficiency 384 * 385 * @dataProvider load_question_discriminative_efficiency_provider 386 * 387 * @param array $quiz1attempts quiz 1 attempts 388 * @param array $expectedquiz1discriminativeefficiency expected quiz 1 discriminative efficiency 389 * @param array $quiz2attempts quiz 2 attempts 390 * @param array $expectedquiz2discriminativeefficiency expected quiz 2 discriminative efficiency 391 * @param array $expectedaveragediscriminativeefficiency expected average discriminative efficiency 392 */ 393 public function test_load_question_discriminative_efficiency( 394 array $quiz1attempts, 395 array $expectedquiz1discriminativeefficiency, 396 array $quiz2attempts, 397 array $expectedquiz2discriminativeefficiency, 398 array $expectedaveragediscriminativeefficiency 399 ): void { 400 $this->resetAfterTest(); 401 402 list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts); 403 404 // Quiz 1 discriminative efficiency. 405 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz1->cmid)); 406 $discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency'); 407 $discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency'); 408 $discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency'); 409 $discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency'); 410 411 $this->assertEquals($expectedquiz1discriminativeefficiency[0], 412 helper::format_percentage($discriminativeefficiency1, false), 413 "Failure in quiz 1 - question 1 discriminative efficiency"); 414 $this->assertEquals($expectedquiz1discriminativeefficiency[1], 415 helper::format_percentage($discriminativeefficiency2, false), 416 "Failure in quiz 1 - question 2 discriminative efficiency"); 417 $this->assertEquals($expectedquiz1discriminativeefficiency[2], 418 helper::format_percentage($discriminativeefficiency3, false), 419 "Failure in quiz 1 - question 3 discriminative efficiency"); 420 $this->assertEquals($expectedquiz1discriminativeefficiency[3], 421 helper::format_percentage($discriminativeefficiency4, false), 422 "Failure in quiz 1 - question 4 discriminative efficiency"); 423 424 // Quiz 2 discriminative efficiency. 425 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz2->cmid)); 426 $discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency'); 427 $discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency'); 428 $discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency'); 429 $discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency'); 430 431 $this->assertEquals($expectedquiz2discriminativeefficiency[0], 432 helper::format_percentage($discriminativeefficiency1, false), 433 "Failure in quiz 2 - question 1 discriminative efficiency"); 434 $this->assertEquals($expectedquiz2discriminativeefficiency[1], 435 helper::format_percentage($discriminativeefficiency2, false), 436 "Failure in quiz 2 - question 2 discriminative efficiency"); 437 $this->assertEquals($expectedquiz2discriminativeefficiency[2], 438 helper::format_percentage($discriminativeefficiency3, false), 439 "Failure in quiz 2 - question 3 discriminative efficiency"); 440 $this->assertEquals($expectedquiz2discriminativeefficiency[3], 441 helper::format_percentage($discriminativeefficiency4, false), 442 "Failure in quiz 2 - question 4 discriminative efficiency"); 443 444 // Average question discriminative efficiency. 445 $avgdiscriminativeefficiency1 = helper::calculate_average_question_discriminative_efficiency($questions[1]->id); 446 $avgdiscriminativeefficiency2 = helper::calculate_average_question_discriminative_efficiency($questions[2]->id); 447 $avgdiscriminativeefficiency3 = helper::calculate_average_question_discriminative_efficiency($questions[3]->id); 448 $avgdiscriminativeefficiency4 = helper::calculate_average_question_discriminative_efficiency($questions[4]->id); 449 450 $this->assertEquals($expectedaveragediscriminativeefficiency[0], 451 helper::format_percentage($avgdiscriminativeefficiency1, false), 452 "Failure in question 1 average discriminative efficiency"); 453 $this->assertEquals($expectedaveragediscriminativeefficiency[1], 454 helper::format_percentage($avgdiscriminativeefficiency2, false), 455 "Failure in question 2 average discriminative efficiency"); 456 $this->assertEquals($expectedaveragediscriminativeefficiency[2], 457 helper::format_percentage($avgdiscriminativeefficiency3, false), 458 "Failure in question 3 average discriminative efficiency"); 459 $this->assertEquals($expectedaveragediscriminativeefficiency[3], 460 helper::format_percentage($avgdiscriminativeefficiency4, false), 461 "Failure in question 4 average discriminative efficiency"); 462 } 463 464 /** 465 * Data provider for {@see test_load_question_discrimination_index()}. 466 * @return \Generator 467 */ 468 public function load_question_discrimination_index_provider(): \Generator { 469 yield 'Discrimination Index' => [ 470 'Quiz 1 attempts' => [ 471 $this->generate_attempt_answers([1, 0, 0, 0]), 472 $this->generate_attempt_answers([1, 1, 0, 0]), 473 $this->generate_attempt_answers([1, 0, 1, 0]), 474 $this->generate_attempt_answers([1, 1, 1, 1]), 475 ], 476 'Expected quiz 1 Discrimination Index' => ['N/A', '30.15%', '30.15%', '81.65%'], 477 'Quiz 2 attempts' => [ 478 $this->generate_attempt_answers([1, 1, 1, 1]), 479 $this->generate_attempt_answers([0, 0, 0, 0]), 480 $this->generate_attempt_answers([1, 0, 0, 1]), 481 $this->generate_attempt_answers([0, 1, 1, 0]), 482 ], 483 'Expected quiz 2 discrimination Index' => ['44.72%', '44.72%', '44.72%', '44.72%'], 484 'Expected average discrimination Index' => ['44.72%', '37.44%', '37.44%', '63.19%'], 485 ]; 486 } 487 488 /** 489 * Test discrimination index 490 * 491 * @dataProvider load_question_discrimination_index_provider 492 * 493 * @param array $quiz1attempts quiz 1 attempts 494 * @param array $expectedquiz1discriminationindex expected quiz 1 discrimination index 495 * @param array $quiz2attempts quiz 2 attempts 496 * @param array $expectedquiz2discriminationindex expected quiz 2 discrimination index 497 * @param array $expectedaveragediscriminationindex expected average discrimination index 498 */ 499 public function test_load_question_discrimination_index( 500 array $quiz1attempts, 501 array $expectedquiz1discriminationindex, 502 array $quiz2attempts, 503 array $expectedquiz2discriminationindex, 504 array $expectedaveragediscriminationindex 505 ): void { 506 $this->resetAfterTest(); 507 508 list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts); 509 510 // Quiz 1 discrimination index. 511 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz1->cmid)); 512 $discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex'); 513 $discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex'); 514 $discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex'); 515 $discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex'); 516 517 $this->assertEquals($expectedquiz1discriminationindex[0], 518 helper::format_percentage($discriminationindex1, false), 519 "Failure in quiz 1 - question 1 discrimination index"); 520 $this->assertEquals($expectedquiz1discriminationindex[1], 521 helper::format_percentage($discriminationindex2, false), 522 "Failure in quiz 1 - question 2 discrimination index"); 523 $this->assertEquals($expectedquiz1discriminationindex[2], 524 helper::format_percentage($discriminationindex3, false), 525 "Failure in quiz 1 - question 3 discrimination index"); 526 $this->assertEquals($expectedquiz1discriminationindex[3], 527 helper::format_percentage($discriminationindex4, false), 528 "Failure in quiz 1 - question 4 discrimination index"); 529 530 // Quiz 2 discrimination index. 531 $stats = $this->load_quiz_statistics_for_place(\context_module::instance($quiz2->cmid)); 532 $discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex'); 533 $discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex'); 534 $discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex'); 535 $discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex'); 536 537 $this->assertEquals($expectedquiz2discriminationindex[0], 538 helper::format_percentage($discriminationindex1, false), 539 "Failure in quiz 2 - question 1 discrimination index"); 540 $this->assertEquals($expectedquiz2discriminationindex[1], 541 helper::format_percentage($discriminationindex2, false), 542 "Failure in quiz 2 - question 2 discrimination index"); 543 $this->assertEquals($expectedquiz2discriminationindex[2], 544 helper::format_percentage($discriminationindex3, false), 545 "Failure in quiz 2 - question 3 discrimination index"); 546 $this->assertEquals($expectedquiz2discriminationindex[3], 547 helper::format_percentage($discriminationindex4, false), 548 "Failure in quiz 2 - question 4 discrimination index"); 549 550 // Average question discrimination index. 551 $avgdiscriminationindex1 = helper::calculate_average_question_discrimination_index($questions[1]->id); 552 $avgdiscriminationindex2 = helper::calculate_average_question_discrimination_index($questions[2]->id); 553 $avgdiscriminationindex3 = helper::calculate_average_question_discrimination_index($questions[3]->id); 554 $avgdiscriminationindex4 = helper::calculate_average_question_discrimination_index($questions[4]->id); 555 556 $this->assertEquals($expectedaveragediscriminationindex[0], 557 helper::format_percentage($avgdiscriminationindex1, false), 558 "Failure in question 1 average discrimination index"); 559 $this->assertEquals($expectedaveragediscriminationindex[1], 560 helper::format_percentage($avgdiscriminationindex2, false), 561 "Failure in question 2 average discrimination index"); 562 $this->assertEquals($expectedaveragediscriminationindex[2], 563 helper::format_percentage($avgdiscriminationindex3, false), 564 "Failure in question 3 average discrimination index"); 565 $this->assertEquals($expectedaveragediscriminationindex[3], 566 helper::format_percentage($avgdiscriminationindex4, false), 567 "Failure in question 4 average discrimination index"); 568 } 569 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body