| Línea 14... |
Línea 14... |
| 14 |
// You should have received a copy of the GNU General Public License
|
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/>.
|
15 |
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
| Línea 16... |
Línea 16... |
| 16 |
|
16 |
|
| Línea 17... |
Línea -... |
| 17 |
namespace core_question\local\statistics;
|
- |
|
| 18 |
|
- |
|
| 19 |
defined('MOODLE_INTERNAL') || die();
|
17 |
namespace core_question\local\statistics;
|
| 20 |
|
18 |
|
| 21 |
use advanced_testcase;
|
19 |
use advanced_testcase;
|
| 22 |
use context;
|
20 |
use context;
|
| 23 |
use context_module;
|
21 |
use context_module;
|
| Línea 28... |
Línea 26... |
| 28 |
use mod_quiz\quiz_attempt;
|
26 |
use mod_quiz\quiz_attempt;
|
| 29 |
use mod_quiz\quiz_settings;
|
27 |
use mod_quiz\quiz_settings;
|
| 30 |
use question_engine;
|
28 |
use question_engine;
|
| 31 |
use ReflectionMethod;
|
29 |
use ReflectionMethod;
|
| Línea 32... |
Línea -... |
| 32 |
|
- |
|
| 33 |
global $CFG;
|
- |
|
| 34 |
require_once($CFG->dirroot . '/mod/quiz/tests/quiz_question_helper_test_trait.php');
|
- |
|
| 35 |
|
30 |
|
| 36 |
/**
|
31 |
/**
|
| 37 |
* Tests for question statistics.
|
32 |
* Tests for question statistics.
|
| 38 |
*
|
33 |
*
|
| 39 |
* @package core_question
|
34 |
* @package core_question
|
| 40 |
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
35 |
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
| 41 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
36 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
| 42 |
* @covers \core_question\local\statistics\statistics_bulk_loader
|
37 |
* @covers \core_question\local\statistics\statistics_bulk_loader
|
| 43 |
*/
|
38 |
*/
|
| 44 |
class statistics_bulk_loader_test extends advanced_testcase {
|
- |
|
| 45 |
|
39 |
final class statistics_bulk_loader_test extends advanced_testcase {
|
| Línea 46... |
Línea 40... |
| 46 |
use \quiz_question_helper_test_trait;
|
40 |
use \mod_quiz\tests\question_helper_test_trait;
|
| 47 |
|
41 |
|
| Línea 48... |
Línea 42... |
| 48 |
/** @var float Delta used when comparing statistics values out-of 1. */
|
42 |
/** @var float Delta used when comparing statistics values out-of 1. */
|
| Línea 69... |
Línea 63... |
| 69 |
// Create three quizzes.
|
63 |
// Create three quizzes.
|
| 70 |
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
|
64 |
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
|
| 71 |
$quiz1 = $quizgenerator->create_instance([
|
65 |
$quiz1 = $quizgenerator->create_instance([
|
| 72 |
'course' => $course->id,
|
66 |
'course' => $course->id,
|
| 73 |
'grade' => 100.0, 'sumgrades' => 2,
|
67 |
'grade' => 100.0, 'sumgrades' => 2,
|
| 74 |
'layout' => '1,2,0'
|
68 |
'layout' => '1,2,0',
|
| 75 |
]);
|
69 |
]);
|
| 76 |
$quiz1context = context_module::instance($quiz1->cmid);
|
70 |
$quiz1context = context_module::instance($quiz1->cmid);
|
| Línea 77... |
Línea 71... |
| 77 |
|
71 |
|
| 78 |
$quiz2 = $quizgenerator->create_instance([
|
72 |
$quiz2 = $quizgenerator->create_instance([
|
| 79 |
'course' => $course->id,
|
73 |
'course' => $course->id,
|
| 80 |
'grade' => 100.0, 'sumgrades' => 2,
|
74 |
'grade' => 100.0, 'sumgrades' => 2,
|
| 81 |
'layout' => '1,2,0'
|
75 |
'layout' => '1,2,0',
|
| 82 |
]);
|
76 |
]);
|
| Línea 83... |
Línea 77... |
| 83 |
$quiz2context = context_module::instance($quiz2->cmid);
|
77 |
$quiz2context = context_module::instance($quiz2->cmid);
|
| 84 |
|
78 |
|
| 85 |
$quiz3 = $quizgenerator->create_instance([
|
79 |
$quiz3 = $quizgenerator->create_instance([
|
| 86 |
'course' => $course->id,
|
80 |
'course' => $course->id,
|
| 87 |
'grade' => 100.0, 'sumgrades' => 2,
|
81 |
'grade' => 100.0, 'sumgrades' => 2,
|
| 88 |
'layout' => '1,2,0'
|
82 |
'layout' => '1,2,0',
|
| Línea 89... |
Línea 83... |
| 89 |
]);
|
83 |
]);
|
| 90 |
$quiz3context = context_module::instance($quiz3->cmid);
|
84 |
$quiz3context = context_module::instance($quiz3->cmid);
|
| Línea 158... |
Línea 152... |
| 158 |
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
|
152 |
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
|
| 159 |
$layout = '1,2,0,3,4,0';
|
153 |
$layout = '1,2,0,3,4,0';
|
| 160 |
$quiz1 = $quizgenerator->create_instance([
|
154 |
$quiz1 = $quizgenerator->create_instance([
|
| 161 |
'course' => $course->id,
|
155 |
'course' => $course->id,
|
| 162 |
'grade' => 100.0, 'sumgrades' => 2,
|
156 |
'grade' => 100.0, 'sumgrades' => 2,
|
| 163 |
'layout' => $layout
|
157 |
'layout' => $layout,
|
| 164 |
]);
|
158 |
]);
|
| Línea 165... |
Línea 159... |
| 165 |
|
159 |
|
| 166 |
$quiz2 = $quizgenerator->create_instance([
|
160 |
$quiz2 = $quizgenerator->create_instance([
|
| 167 |
'course' => $course->id,
|
161 |
'course' => $course->id,
|
| 168 |
'grade' => 100.0, 'sumgrades' => 2,
|
162 |
'grade' => 100.0, 'sumgrades' => 2,
|
| 169 |
'layout' => $layout
|
163 |
'layout' => $layout,
|
| Línea 170... |
Línea 164... |
| 170 |
]);
|
164 |
]);
|
| 171 |
|
165 |
|
| 172 |
/** @var core_question_generator $questiongenerator */
|
166 |
/** @var core_question_generator $questiongenerator */
|
| Línea 208... |
Línea 202... |
| 208 |
quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
|
202 |
quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
|
| 209 |
quiz_attempt_save_started($quizobj, $quba, $attempt);
|
203 |
quiz_attempt_save_started($quizobj, $quba, $attempt);
|
| 210 |
// Submit attempt.
|
204 |
// Submit attempt.
|
| 211 |
$attemptobj = quiz_attempt::create($attempt->id);
|
205 |
$attemptobj = quiz_attempt::create($attempt->id);
|
| 212 |
$attemptobj->process_submitted_actions($timenow, false, $answers);
|
206 |
$attemptobj->process_submitted_actions($timenow, false, $answers);
|
| 213 |
$attemptobj->process_finish($timenow, false);
|
207 |
$attemptobj->process_submit($timenow, false);
|
| - |
|
208 |
$attemptobj->process_grade_submission($timenow);
|
| 214 |
}
|
209 |
}
|
| Línea 215... |
Línea 210... |
| 215 |
|
210 |
|
| 216 |
/**
|
211 |
/**
|
| 217 |
* Generate attempt answers.
|
212 |
* Generate attempt answers.
|
| Línea 220... |
Línea 215... |
| 220 |
* 1 : generate correct answer
|
215 |
* 1 : generate correct answer
|
| 221 |
* 0 : generate wrong answer
|
216 |
* 0 : generate wrong answer
|
| 222 |
*
|
217 |
*
|
| 223 |
* @return array
|
218 |
* @return array
|
| 224 |
*/
|
219 |
*/
|
| 225 |
private function generate_attempt_answers(array $correctanswerflags): array {
|
220 |
private static function generate_attempt_answers(array $correctanswerflags): array {
|
| 226 |
$attempt = [];
|
221 |
$attempt = [];
|
| 227 |
for ($i = 1; $i <= 4; $i++) {
|
222 |
for ($i = 1; $i <= 4; $i++) {
|
| 228 |
if (isset($correctanswerflags) && $correctanswerflags[$i - 1] == 1) {
|
223 |
if (isset($correctanswerflags) && $correctanswerflags[$i - 1] == 1) {
|
| 229 |
// Correct answer.
|
224 |
// Correct answer.
|
| 230 |
$attempt[$i] = ['answer' => 'frog'];
|
225 |
$attempt[$i] = ['answer' => 'frog'];
|
| Línea 242... |
Línea 237... |
| 242 |
* @param array $quiz2attempts quiz 2 attempts
|
237 |
* @param array $quiz2attempts quiz 2 attempts
|
| 243 |
*
|
238 |
*
|
| 244 |
* @return array
|
239 |
* @return array
|
| 245 |
*/
|
240 |
*/
|
| 246 |
private function prepare_and_submit_quizzes(array $quiz1attempts, array $quiz2attempts): array {
|
241 |
private function prepare_and_submit_quizzes(array $quiz1attempts, array $quiz2attempts): array {
|
| 247 |
list($quiz1, $quiz2, $questions) = $this->prepare_quizzes();
|
242 |
[$quiz1, $quiz2, $questions] = $this->prepare_quizzes();
|
| 248 |
// Submit attempts of quiz1.
|
243 |
// Submit attempts of quiz1.
|
| 249 |
foreach ($quiz1attempts as $attempt) {
|
244 |
foreach ($quiz1attempts as $attempt) {
|
| 250 |
$this->submit_quiz($quiz1, $attempt);
|
245 |
$this->submit_quiz($quiz1, $attempt);
|
| 251 |
}
|
246 |
}
|
| 252 |
// Submit attempts of quiz2.
|
247 |
// Submit attempts of quiz2.
|
| Línea 267... |
Línea 262... |
| 267 |
* @param all_calculated_for_qubaid_condition $statistics the batch of statistics.
|
262 |
* @param all_calculated_for_qubaid_condition $statistics the batch of statistics.
|
| 268 |
* @param int $questionid a question id.
|
263 |
* @param int $questionid a question id.
|
| 269 |
* @param string $item one of the field names in all_calculated_for_qubaid_condition, e.g. 'facility'.
|
264 |
* @param string $item one of the field names in all_calculated_for_qubaid_condition, e.g. 'facility'.
|
| 270 |
* @return float|null the required value.
|
265 |
* @return float|null the required value.
|
| 271 |
*/
|
266 |
*/
|
| - |
|
267 |
private function extract_item_value(
|
| 272 |
private function extract_item_value(all_calculated_for_qubaid_condition $statistics,
|
268 |
all_calculated_for_qubaid_condition $statistics,
|
| 273 |
int $questionid, string $item): ?float {
|
269 |
int $questionid,
|
| - |
|
270 |
string $item
|
| - |
|
271 |
): ?float {
|
| 274 |
$rcm = new ReflectionMethod(statistics_bulk_loader::class, 'extract_item_value');
|
272 |
$rcm = new ReflectionMethod(statistics_bulk_loader::class, 'extract_item_value');
|
| 275 |
return $rcm->invoke(null, $statistics, $questionid, $item);
|
273 |
return $rcm->invoke(null, $statistics, $questionid, $item);
|
| 276 |
}
|
274 |
}
|
| Línea 277... |
Línea 275... |
| 277 |
|
275 |
|
| Línea 289... |
Línea 287... |
| 289 |
/**
|
287 |
/**
|
| 290 |
* Data provider for {@see test_load_question_facility()}.
|
288 |
* Data provider for {@see test_load_question_facility()}.
|
| 291 |
*
|
289 |
*
|
| 292 |
* @return Generator
|
290 |
* @return Generator
|
| 293 |
*/
|
291 |
*/
|
| 294 |
public function load_question_facility_provider(): Generator {
|
292 |
public static function load_question_facility_provider(): Generator {
|
| 295 |
yield 'Facility case 1' => [
|
293 |
yield 'Facility case 1' => [
|
| 296 |
'Quiz 1 attempts' => [
|
294 |
// Quiz 1 attempts.
|
| - |
|
295 |
[
|
| 297 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
296 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 298 |
],
|
297 |
],
|
| 299 |
'Expected quiz 1 facilities' => [1.0, 0.0, 0.0, 0.0],
|
298 |
// Expected quiz 1 facilities.
|
| - |
|
299 |
[1.0, 0.0, 0.0, 0.0],
|
| 300 |
'Quiz 2 attempts' => [
|
300 |
// Quiz 2 attempts.
|
| - |
|
301 |
[
|
| 301 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
302 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 302 |
$this->generate_attempt_answers([1, 1, 0, 0]),
|
303 |
self::generate_attempt_answers([1, 1, 0, 0]),
|
| 303 |
],
|
304 |
],
|
| 304 |
'Expected quiz 2 facilities' => [1.0, 0.5, 0.0, 0.0],
|
305 |
// Expected quiz 2 facilities.
|
| - |
|
306 |
[1.0, 0.5, 0.0, 0.0],
|
| 305 |
'Expected average facilities' => [1.0, 0.25, 0.0, 0.0],
|
307 |
// Expected average facilities.
|
| - |
|
308 |
[1.0, 0.25, 0.0, 0.0],
|
| 306 |
];
|
309 |
];
|
| 307 |
yield 'Facility case 2' => [
|
310 |
yield 'Facility case 2' => [
|
| 308 |
'Quiz 1 attempts' => [
|
311 |
// Quiz 1 attempts.
|
| - |
|
312 |
[
|
| 309 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
313 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 310 |
$this->generate_attempt_answers([1, 1, 0, 0]),
|
314 |
self::generate_attempt_answers([1, 1, 0, 0]),
|
| 311 |
$this->generate_attempt_answers([1, 1, 1, 0]),
|
315 |
self::generate_attempt_answers([1, 1, 1, 0]),
|
| 312 |
],
|
316 |
],
|
| - |
|
317 |
// Expected quiz 1 facilities.
|
| 313 |
'Expected quiz 1 facilities' => [1.0, 0.6667, 0.3333, 0.0],
|
318 |
[1.0, 0.6667, 0.3333, 0.0],
|
| 314 |
'Quiz 2 attempts' => [
|
319 |
// Quiz 2 attempts.
|
| - |
|
320 |
[
|
| 315 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
321 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 316 |
$this->generate_attempt_answers([1, 1, 0, 0]),
|
322 |
self::generate_attempt_answers([1, 1, 0, 0]),
|
| 317 |
$this->generate_attempt_answers([1, 1, 1, 0]),
|
323 |
self::generate_attempt_answers([1, 1, 1, 0]),
|
| 318 |
$this->generate_attempt_answers([1, 1, 1, 1]),
|
324 |
self::generate_attempt_answers([1, 1, 1, 1]),
|
| 319 |
],
|
325 |
],
|
| 320 |
'Expected quiz 2 facilities' => [1.0, 0.75, 0.5, 0.25],
|
326 |
// Expected quiz 2 facilities.
|
| - |
|
327 |
[1.0, 0.75, 0.5, 0.25],
|
| - |
|
328 |
// Expected average facilities.
|
| 321 |
'Expected average facilities' => [1.0, 0.7083, 0.4167, 0.1250],
|
329 |
[1.0, 0.7083, 0.4167, 0.1250],
|
| 322 |
];
|
330 |
];
|
| 323 |
}
|
331 |
}
|
| Línea 324... |
Línea 332... |
| 324 |
|
332 |
|
| 325 |
/**
|
333 |
/**
|
| Línea 340... |
Línea 348... |
| 340 |
array $expectedquiz2facilities,
|
348 |
array $expectedquiz2facilities,
|
| 341 |
array $expectedaveragefacilities
|
349 |
array $expectedaveragefacilities
|
| 342 |
): void {
|
350 |
): void {
|
| 343 |
$this->resetAfterTest();
|
351 |
$this->resetAfterTest();
|
| Línea 344... |
Línea 352... |
| 344 |
|
352 |
|
| Línea 345... |
Línea 353... |
| 345 |
list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
353 |
[$quiz1, $quiz2, $questions] = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
| 346 |
|
354 |
|
| 347 |
// Quiz 1 facilities.
|
355 |
// Quiz 1 facilities.
|
| 348 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
356 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
| Línea 372... |
Línea 380... |
| 372 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
380 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
| 373 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
381 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
| 374 |
['facility']
|
382 |
['facility']
|
| 375 |
);
|
383 |
);
|
| Línea -... |
Línea 384... |
| - |
|
384 |
|
| 376 |
|
385 |
$this->assertEqualsWithDelta(
|
| 377 |
$this->assertEqualsWithDelta($expectedaveragefacilities[0],
|
386 |
$expectedaveragefacilities[0],
|
| - |
|
387 |
$stats[$questions[1]->id]['facility'],
|
| - |
|
388 |
self::DELTA
|
| - |
|
389 |
);
|
| 378 |
$stats[$questions[1]->id]['facility'], self::DELTA);
|
390 |
$this->assertEqualsWithDelta(
|
| 379 |
$this->assertEqualsWithDelta($expectedaveragefacilities[1],
|
391 |
$expectedaveragefacilities[1],
|
| - |
|
392 |
$stats[$questions[2]->id]['facility'],
|
| - |
|
393 |
self::DELTA
|
| - |
|
394 |
);
|
| 380 |
$stats[$questions[2]->id]['facility'], self::DELTA);
|
395 |
$this->assertEqualsWithDelta(
|
| 381 |
$this->assertEqualsWithDelta($expectedaveragefacilities[2],
|
396 |
$expectedaveragefacilities[2],
|
| - |
|
397 |
$stats[$questions[3]->id]['facility'],
|
| - |
|
398 |
self::DELTA
|
| - |
|
399 |
);
|
| 382 |
$stats[$questions[3]->id]['facility'], self::DELTA);
|
400 |
$this->assertEqualsWithDelta(
|
| 383 |
$this->assertEqualsWithDelta($expectedaveragefacilities[3],
|
401 |
$expectedaveragefacilities[3],
|
| - |
|
402 |
$stats[$questions[4]->id]['facility'],
|
| - |
|
403 |
self::DELTA
|
| 384 |
$stats[$questions[4]->id]['facility'], self::DELTA);
|
404 |
);
|
| Línea 385... |
Línea 405... |
| 385 |
}
|
405 |
}
|
| 386 |
|
406 |
|
| 387 |
/**
|
407 |
/**
|
| 388 |
* Data provider for {@see test_load_question_discriminative_efficiency()}.
|
408 |
* Data provider for {@see test_load_question_discriminative_efficiency()}.
|
| 389 |
* @return Generator
|
409 |
* @return Generator
|
| 390 |
*/
|
410 |
*/
|
| 391 |
public function load_question_discriminative_efficiency_provider(): Generator {
|
411 |
public static function load_question_discriminative_efficiency_provider(): Generator {
|
| - |
|
412 |
yield 'Discriminative efficiency' => [
|
| 392 |
yield 'Discriminative efficiency' => [
|
413 |
// Quiz 1 attempts.
|
| 393 |
'Quiz 1 attempts' => [
|
414 |
[
|
| 394 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
415 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 395 |
$this->generate_attempt_answers([1, 1, 0, 0]),
|
416 |
self::generate_attempt_answers([1, 1, 0, 0]),
|
| 396 |
$this->generate_attempt_answers([1, 0, 1, 0]),
|
417 |
self::generate_attempt_answers([1, 0, 1, 0]),
|
| 397 |
$this->generate_attempt_answers([1, 1, 1, 1]),
|
418 |
self::generate_attempt_answers([1, 1, 1, 1]),
|
| - |
|
419 |
],
|
| 398 |
],
|
420 |
// Expected quiz 1 discriminative efficiency.
|
| - |
|
421 |
[null, 33.33, 33.33, 100.00],
|
| 399 |
'Expected quiz 1 discriminative efficiency' => [null, 33.33, 33.33, 100.00],
|
422 |
// Quiz 2 attempts.
|
| 400 |
'Quiz 2 attempts' => [
|
423 |
[
|
| 401 |
$this->generate_attempt_answers([1, 1, 1, 1]),
|
424 |
self::generate_attempt_answers([1, 1, 1, 1]),
|
| 402 |
$this->generate_attempt_answers([0, 0, 0, 0]),
|
425 |
self::generate_attempt_answers([0, 0, 0, 0]),
|
| 403 |
$this->generate_attempt_answers([1, 0, 0, 1]),
|
426 |
self::generate_attempt_answers([1, 0, 0, 1]),
|
| 404 |
$this->generate_attempt_answers([0, 1, 1, 0]),
|
427 |
self::generate_attempt_answers([0, 1, 1, 0]),
|
| - |
|
428 |
],
|
| 405 |
],
|
429 |
// Expected quiz 2 discriminative efficiency.
|
| - |
|
430 |
[50.00, 50.00, 50.00, 50.00],
|
| 406 |
'Expected quiz 2 discriminative efficiency' => [50.00, 50.00, 50.00, 50.00],
|
431 |
// Expected average discriminative efficiency.
|
| 407 |
'Expected average discriminative efficiency' => [50.00, 41.67, 41.67, 75.00],
|
432 |
[50.00, 41.67, 41.67, 75.00],
|
| Línea 408... |
Línea 433... |
| 408 |
];
|
433 |
];
|
| 409 |
}
|
434 |
}
|
| Línea 426... |
Línea 451... |
| 426 |
array $expectedquiz2discriminativeefficiency,
|
451 |
array $expectedquiz2discriminativeefficiency,
|
| 427 |
array $expectedaveragediscriminativeefficiency
|
452 |
array $expectedaveragediscriminativeefficiency
|
| 428 |
): void {
|
453 |
): void {
|
| 429 |
$this->resetAfterTest();
|
454 |
$this->resetAfterTest();
|
| Línea 430... |
Línea 455... |
| 430 |
|
455 |
|
| Línea 431... |
Línea 456... |
| 431 |
list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
456 |
[$quiz1, $quiz2, $questions] = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
| 432 |
|
457 |
|
| 433 |
// Quiz 1 discriminative efficiency.
|
458 |
// Quiz 1 discriminative efficiency.
|
| 434 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
459 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
| 435 |
$discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency');
|
460 |
$discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency');
|
| 436 |
$discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency');
|
461 |
$discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency');
|
| Línea -... |
Línea 462... |
| - |
|
462 |
$discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency');
|
| 437 |
$discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency');
|
463 |
$discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency');
|
| 438 |
$discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency');
|
464 |
|
| - |
|
465 |
$this->assertEqualsWithDelta(
|
| - |
|
466 |
$expectedquiz1discriminativeefficiency[0],
|
| - |
|
467 |
$discriminativeefficiency1,
|
| 439 |
|
468 |
self::PERCENT_DELTA
|
| 440 |
$this->assertEqualsWithDelta($expectedquiz1discriminativeefficiency[0],
|
469 |
);
|
| - |
|
470 |
$this->assertEqualsWithDelta(
|
| - |
|
471 |
$expectedquiz1discriminativeefficiency[1],
|
| - |
|
472 |
$discriminativeefficiency2,
|
| 441 |
$discriminativeefficiency1, self::PERCENT_DELTA);
|
473 |
self::PERCENT_DELTA
|
| 442 |
$this->assertEqualsWithDelta($expectedquiz1discriminativeefficiency[1],
|
474 |
);
|
| - |
|
475 |
$this->assertEqualsWithDelta(
|
| - |
|
476 |
$expectedquiz1discriminativeefficiency[2],
|
| - |
|
477 |
$discriminativeefficiency3,
|
| 443 |
$discriminativeefficiency2, self::PERCENT_DELTA);
|
478 |
self::PERCENT_DELTA
|
| 444 |
$this->assertEqualsWithDelta($expectedquiz1discriminativeefficiency[2],
|
479 |
);
|
| - |
|
480 |
$this->assertEqualsWithDelta(
|
| - |
|
481 |
$expectedquiz1discriminativeefficiency[3],
|
| Línea 445... |
Línea 482... |
| 445 |
$discriminativeefficiency3, self::PERCENT_DELTA);
|
482 |
$discriminativeefficiency4,
|
| 446 |
$this->assertEqualsWithDelta($expectedquiz1discriminativeefficiency[3],
|
483 |
self::PERCENT_DELTA
|
| 447 |
$discriminativeefficiency4, self::PERCENT_DELTA);
|
484 |
);
|
| 448 |
|
485 |
|
| 449 |
// Quiz 2 discriminative efficiency.
|
486 |
// Quiz 2 discriminative efficiency.
|
| 450 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz2->cmid));
|
487 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz2->cmid));
|
| Línea -... |
Línea 488... |
| - |
|
488 |
$discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency');
|
| 451 |
$discriminativeefficiency1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminativeefficiency');
|
489 |
$discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency');
|
| 452 |
$discriminativeefficiency2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminativeefficiency');
|
490 |
$discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency');
|
| - |
|
491 |
$discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency');
|
| - |
|
492 |
|
| - |
|
493 |
$this->assertEqualsWithDelta(
|
| 453 |
$discriminativeefficiency3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminativeefficiency');
|
494 |
$expectedquiz2discriminativeefficiency[0],
|
| 454 |
$discriminativeefficiency4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminativeefficiency');
|
495 |
$discriminativeefficiency1,
|
| - |
|
496 |
self::PERCENT_DELTA
|
| - |
|
497 |
);
|
| - |
|
498 |
$this->assertEqualsWithDelta(
|
| 455 |
|
499 |
$expectedquiz2discriminativeefficiency[1],
|
| 456 |
$this->assertEqualsWithDelta($expectedquiz2discriminativeefficiency[0],
|
500 |
$discriminativeefficiency2,
|
| - |
|
501 |
self::PERCENT_DELTA
|
| - |
|
502 |
);
|
| - |
|
503 |
$this->assertEqualsWithDelta(
|
| 457 |
$discriminativeefficiency1, self::PERCENT_DELTA);
|
504 |
$expectedquiz2discriminativeefficiency[2],
|
| 458 |
$this->assertEqualsWithDelta($expectedquiz2discriminativeefficiency[1],
|
505 |
$discriminativeefficiency3,
|
| - |
|
506 |
self::PERCENT_DELTA
|
| - |
|
507 |
);
|
| Línea 459... |
Línea 508... |
| 459 |
$discriminativeefficiency2, self::PERCENT_DELTA);
|
508 |
$this->assertEqualsWithDelta(
|
| 460 |
$this->assertEqualsWithDelta($expectedquiz2discriminativeefficiency[2],
|
509 |
$expectedquiz2discriminativeefficiency[3],
|
| 461 |
$discriminativeefficiency3, self::PERCENT_DELTA);
|
510 |
$discriminativeefficiency4,
|
| 462 |
$this->assertEqualsWithDelta($expectedquiz2discriminativeefficiency[3],
|
511 |
self::PERCENT_DELTA
|
| 463 |
$discriminativeefficiency4, self::PERCENT_DELTA);
|
512 |
);
|
| Línea -... |
Línea 513... |
| - |
|
513 |
|
| 464 |
|
514 |
// Average question discriminative efficiency.
|
| 465 |
// Average question discriminative efficiency.
|
515 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
| - |
|
516 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
| - |
|
517 |
['discriminativeefficiency']
|
| - |
|
518 |
);
|
| 466 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
519 |
|
| 467 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
520 |
$this->assertEqualsWithDelta(
|
| - |
|
521 |
$expectedaveragediscriminativeefficiency[0],
|
| - |
|
522 |
$stats[$questions[1]->id]['discriminativeefficiency'],
|
| - |
|
523 |
self::PERCENT_DELTA
|
| 468 |
['discriminativeefficiency']
|
524 |
);
|
| 469 |
);
|
525 |
$this->assertEqualsWithDelta(
|
| - |
|
526 |
$expectedaveragediscriminativeefficiency[1],
|
| - |
|
527 |
$stats[$questions[2]->id]['discriminativeefficiency'],
|
| - |
|
528 |
self::PERCENT_DELTA
|
| 470 |
|
529 |
);
|
| 471 |
$this->assertEqualsWithDelta($expectedaveragediscriminativeefficiency[0],
|
530 |
$this->assertEqualsWithDelta(
|
| - |
|
531 |
$expectedaveragediscriminativeefficiency[2],
|
| - |
|
532 |
$stats[$questions[3]->id]['discriminativeefficiency'],
|
| 472 |
$stats[$questions[1]->id]['discriminativeefficiency'], self::PERCENT_DELTA);
|
533 |
self::PERCENT_DELTA
|
| Línea 473... |
Línea 534... |
| 473 |
$this->assertEqualsWithDelta($expectedaveragediscriminativeefficiency[1],
|
534 |
);
|
| 474 |
$stats[$questions[2]->id]['discriminativeefficiency'], self::PERCENT_DELTA);
|
535 |
$this->assertEqualsWithDelta(
|
| 475 |
$this->assertEqualsWithDelta($expectedaveragediscriminativeefficiency[2],
|
536 |
$expectedaveragediscriminativeefficiency[3],
|
| 476 |
$stats[$questions[3]->id]['discriminativeefficiency'], self::PERCENT_DELTA);
|
537 |
$stats[$questions[4]->id]['discriminativeefficiency'],
|
| 477 |
$this->assertEqualsWithDelta($expectedaveragediscriminativeefficiency[3],
|
538 |
self::PERCENT_DELTA
|
| 478 |
$stats[$questions[4]->id]['discriminativeefficiency'], self::PERCENT_DELTA);
|
539 |
);
|
| 479 |
}
|
540 |
}
|
| - |
|
541 |
|
| 480 |
|
542 |
/**
|
| 481 |
/**
|
543 |
* Data provider for {@see test_load_question_discrimination_index()}.
|
| 482 |
* Data provider for {@see test_load_question_discrimination_index()}.
|
544 |
* @return Generator
|
| 483 |
* @return Generator
|
545 |
*/
|
| 484 |
*/
|
546 |
public static function load_question_discrimination_index_provider(): Generator {
|
| 485 |
public function load_question_discrimination_index_provider(): Generator {
|
547 |
yield 'Discrimination Index' => [
|
| - |
|
548 |
// Quiz 1 attempts.
|
| 486 |
yield 'Discrimination Index' => [
|
549 |
[
|
| - |
|
550 |
self::generate_attempt_answers([1, 0, 0, 0]),
|
| 487 |
'Quiz 1 attempts' => [
|
551 |
self::generate_attempt_answers([1, 1, 0, 0]),
|
| 488 |
$this->generate_attempt_answers([1, 0, 0, 0]),
|
552 |
self::generate_attempt_answers([1, 0, 1, 0]),
|
| 489 |
$this->generate_attempt_answers([1, 1, 0, 0]),
|
553 |
self::generate_attempt_answers([1, 1, 1, 1]),
|
| 490 |
$this->generate_attempt_answers([1, 0, 1, 0]),
|
554 |
],
|
| 491 |
$this->generate_attempt_answers([1, 1, 1, 1]),
|
555 |
// Expected quiz 1 Discrimination Index.
|
| 492 |
],
|
556 |
[null, 30.15, 30.15, 81.65],
|
| - |
|
557 |
// Quiz 2 attempts.
|
| 493 |
'Expected quiz 1 Discrimination Index' => [null, 30.15, 30.15, 81.65],
|
558 |
[
|
| - |
|
559 |
self::generate_attempt_answers([1, 1, 1, 1]),
|
| 494 |
'Quiz 2 attempts' => [
|
560 |
self::generate_attempt_answers([0, 0, 0, 0]),
|
| 495 |
$this->generate_attempt_answers([1, 1, 1, 1]),
|
561 |
self::generate_attempt_answers([1, 0, 0, 1]),
|
| Línea 496... |
Línea 562... |
| 496 |
$this->generate_attempt_answers([0, 0, 0, 0]),
|
562 |
self::generate_attempt_answers([0, 1, 1, 0]),
|
| 497 |
$this->generate_attempt_answers([1, 0, 0, 1]),
|
563 |
],
|
| Línea 520... |
Línea 586... |
| 520 |
array $expectedquiz2discriminationindex,
|
586 |
array $expectedquiz2discriminationindex,
|
| 521 |
array $expectedaveragediscriminationindex
|
587 |
array $expectedaveragediscriminationindex
|
| 522 |
): void {
|
588 |
): void {
|
| 523 |
$this->resetAfterTest();
|
589 |
$this->resetAfterTest();
|
| Línea 524... |
Línea 590... |
| 524 |
|
590 |
|
| Línea 525... |
Línea 591... |
| 525 |
list($quiz1, $quiz2, $questions) = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
591 |
[$quiz1, $quiz2, $questions] = $this->prepare_and_submit_quizzes($quiz1attempts, $quiz2attempts);
|
| 526 |
|
592 |
|
| 527 |
// Quiz 1 discrimination index.
|
593 |
// Quiz 1 discrimination index.
|
| 528 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
594 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz1->cmid));
|
| 529 |
$discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex');
|
595 |
$discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex');
|
| 530 |
$discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex');
|
596 |
$discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex');
|
| Línea -... |
Línea 597... |
| - |
|
597 |
$discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex');
|
| 531 |
$discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex');
|
598 |
$discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex');
|
| 532 |
$discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex');
|
599 |
|
| - |
|
600 |
$this->assertEqualsWithDelta(
|
| - |
|
601 |
$expectedquiz1discriminationindex[0],
|
| - |
|
602 |
$discriminationindex1,
|
| 533 |
|
603 |
self::PERCENT_DELTA
|
| 534 |
$this->assertEqualsWithDelta($expectedquiz1discriminationindex[0],
|
604 |
);
|
| - |
|
605 |
$this->assertEqualsWithDelta(
|
| - |
|
606 |
$expectedquiz1discriminationindex[1],
|
| - |
|
607 |
$discriminationindex2,
|
| 535 |
$discriminationindex1, self::PERCENT_DELTA);
|
608 |
self::PERCENT_DELTA
|
| 536 |
$this->assertEqualsWithDelta($expectedquiz1discriminationindex[1],
|
609 |
);
|
| - |
|
610 |
$this->assertEqualsWithDelta(
|
| - |
|
611 |
$expectedquiz1discriminationindex[2],
|
| - |
|
612 |
$discriminationindex3,
|
| 537 |
$discriminationindex2, self::PERCENT_DELTA);
|
613 |
self::PERCENT_DELTA
|
| 538 |
$this->assertEqualsWithDelta($expectedquiz1discriminationindex[2],
|
614 |
);
|
| - |
|
615 |
$this->assertEqualsWithDelta(
|
| - |
|
616 |
$expectedquiz1discriminationindex[3],
|
| Línea 539... |
Línea 617... |
| 539 |
$discriminationindex3, self::PERCENT_DELTA);
|
617 |
$discriminationindex4,
|
| 540 |
$this->assertEqualsWithDelta($expectedquiz1discriminationindex[3],
|
618 |
self::PERCENT_DELTA
|
| 541 |
$discriminationindex4, self::PERCENT_DELTA);
|
619 |
);
|
| 542 |
|
620 |
|
| 543 |
// Quiz 2 discrimination index.
|
621 |
// Quiz 2 discrimination index.
|
| 544 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz2->cmid));
|
622 |
$stats = $this->load_quiz_statistics_for_place(context_module::instance($quiz2->cmid));
|
| Línea -... |
Línea 623... |
| - |
|
623 |
$discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex');
|
| 545 |
$discriminationindex1 = $this->extract_item_value($stats, $questions[1]->id, 'discriminationindex');
|
624 |
$discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex');
|
| 546 |
$discriminationindex2 = $this->extract_item_value($stats, $questions[2]->id, 'discriminationindex');
|
625 |
$discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex');
|
| - |
|
626 |
$discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex');
|
| - |
|
627 |
|
| - |
|
628 |
$this->assertEqualsWithDelta(
|
| 547 |
$discriminationindex3 = $this->extract_item_value($stats, $questions[3]->id, 'discriminationindex');
|
629 |
$expectedquiz2discriminationindex[0],
|
| 548 |
$discriminationindex4 = $this->extract_item_value($stats, $questions[4]->id, 'discriminationindex');
|
630 |
$discriminationindex1,
|
| - |
|
631 |
self::PERCENT_DELTA
|
| - |
|
632 |
);
|
| - |
|
633 |
$this->assertEqualsWithDelta(
|
| 549 |
|
634 |
$expectedquiz2discriminationindex[1],
|
| 550 |
$this->assertEqualsWithDelta($expectedquiz2discriminationindex[0],
|
635 |
$discriminationindex2,
|
| - |
|
636 |
self::PERCENT_DELTA
|
| - |
|
637 |
);
|
| - |
|
638 |
$this->assertEqualsWithDelta(
|
| 551 |
$discriminationindex1, self::PERCENT_DELTA);
|
639 |
$expectedquiz2discriminationindex[2],
|
| 552 |
$this->assertEqualsWithDelta($expectedquiz2discriminationindex[1],
|
640 |
$discriminationindex3,
|
| - |
|
641 |
self::PERCENT_DELTA
|
| - |
|
642 |
);
|
| Línea 553... |
Línea 643... |
| 553 |
$discriminationindex2, self::PERCENT_DELTA);
|
643 |
$this->assertEqualsWithDelta(
|
| 554 |
$this->assertEqualsWithDelta($expectedquiz2discriminationindex[2],
|
644 |
$expectedquiz2discriminationindex[3],
|
| 555 |
$discriminationindex3, self::PERCENT_DELTA);
|
645 |
$discriminationindex4,
|
| 556 |
$this->assertEqualsWithDelta($expectedquiz2discriminationindex[3],
|
646 |
self::PERCENT_DELTA
|
| 557 |
$discriminationindex4, self::PERCENT_DELTA);
|
647 |
);
|
| Línea -... |
Línea 648... |
| - |
|
648 |
|
| 558 |
|
649 |
// Average question discrimination index.
|
| 559 |
// Average question discrimination index.
|
650 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
| - |
|
651 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
| - |
|
652 |
['discriminationindex']
|
| - |
|
653 |
);
|
| 560 |
$stats = statistics_bulk_loader::load_aggregate_statistics(
|
654 |
|
| 561 |
[$questions[1]->id, $questions[2]->id, $questions[3]->id, $questions[4]->id],
|
655 |
$this->assertEqualsWithDelta(
|
| - |
|
656 |
$expectedaveragediscriminationindex[0],
|
| - |
|
657 |
$stats[$questions[1]->id]['discriminationindex'],
|
| - |
|
658 |
self::PERCENT_DELTA
|
| 562 |
['discriminationindex']
|
659 |
);
|
| 563 |
);
|
660 |
$this->assertEqualsWithDelta(
|
| - |
|
661 |
$expectedaveragediscriminationindex[1],
|
| - |
|
662 |
$stats[$questions[2]->id]['discriminationindex'],
|
| - |
|
663 |
self::PERCENT_DELTA
|
| 564 |
|
664 |
);
|
| 565 |
$this->assertEqualsWithDelta($expectedaveragediscriminationindex[0],
|
665 |
$this->assertEqualsWithDelta(
|
| - |
|
666 |
$expectedaveragediscriminationindex[2],
|
| - |
|
667 |
$stats[$questions[3]->id]['discriminationindex'],
|
| 566 |
$stats[$questions[1]->id]['discriminationindex'], self::PERCENT_DELTA);
|
668 |
self::PERCENT_DELTA
|
| Línea 567... |
Línea 669... |
| 567 |
$this->assertEqualsWithDelta($expectedaveragediscriminationindex[1],
|
669 |
);
|
| 568 |
$stats[$questions[2]->id]['discriminationindex'], self::PERCENT_DELTA);
|
670 |
$this->assertEqualsWithDelta(
|
| 569 |
$this->assertEqualsWithDelta($expectedaveragediscriminationindex[2],
|
671 |
$expectedaveragediscriminationindex[3],
|
| 570 |
$stats[$questions[3]->id]['discriminationindex'], self::PERCENT_DELTA);
|
672 |
$stats[$questions[4]->id]['discriminationindex'],
|
| 571 |
$this->assertEqualsWithDelta($expectedaveragediscriminationindex[3],
|
673 |
self::PERCENT_DELTA
|
| Línea 572... |
Línea 674... |
| 572 |
$stats[$questions[4]->id]['discriminationindex'], self::PERCENT_DELTA);
|
674 |
);
|
| 573 |
}
|
675 |
}
|
| 574 |
|
676 |
|
| 575 |
/**
|
677 |
/**
|
| Línea 576... |
Línea 678... |
| 576 |
* Test with question statistics disabled
|
678 |
* Test with question statistics disabled
|
| 577 |
*/
|
679 |
*/
|
| 578 |
public function test_statistics_disabled(): void {
|
680 |
public function test_statistics_disabled(): void {
|