@@ -87,16 +87,15 @@ abstract class strategy {
87
87
*/
88
88
public int $ catcontextid ;
89
89
90
- /**
91
- * @var array<preselect_task>
92
- */
93
- public array $ scoremodifiers ;
94
-
95
90
/**
96
91
* @var progress
97
92
*/
98
93
protected progress $ progress ;
99
94
95
+ private cache $ cache ;
96
+
97
+ private $ result ;
98
+
100
99
/**
101
100
* These data provide the context for the selection of the next question.
102
101
*
@@ -115,8 +114,7 @@ abstract class strategy {
115
114
public function __construct () {
116
115
global $ CFG ;
117
116
require_once ($ CFG ->dirroot . '/local/catquiz/lib.php ' );
118
-
119
- $ this ->scoremodifiers = info::get_score_modifiers ();
117
+ $ this ->cache = cache::make ('local_catquiz ' , 'adaptivequizattempt ' );
120
118
}
121
119
122
120
/**
@@ -160,15 +158,14 @@ public function get_description(): string {
160
158
*/
161
159
public function return_next_testitem (array $ context ) {
162
160
$ this ->context = $ context ;
163
- $ cache = cache::make ('local_catquiz ' , 'adaptivequizattempt ' );
164
161
$ maxtime = $ context ['progress ' ]->get_starttime () + $ context ['max_attempttime_in_sec ' ];
165
162
if (time () > $ maxtime ) {
166
163
// The 'endtime' holds the last timepoint that is relevant for the
167
164
// result. So if a student tries to answer a question after the
168
165
// time limit, this value is set to the time limit (starttime + max
169
166
// attempt time).
170
- $ cache ->set ('endtime ' , $ maxtime );
171
- $ cache ->set ('catquizerror ' , status::EXCEEDED_MAX_ATTEMPT_TIME );
167
+ $ this -> cache ->set ('endtime ' , $ maxtime );
168
+ $ this -> cache ->set ('catquizerror ' , status::EXCEEDED_MAX_ATTEMPT_TIME );
172
169
return result::err (status::EXCEEDED_MAX_ATTEMPT_TIME );
173
170
}
174
171
@@ -193,96 +190,63 @@ public function return_next_testitem(array $context) {
193
190
}
194
191
195
192
// Core methods called in every strategy.
196
- $ res = $ this ->update_personability ();
197
- if ($ res ->iserr ()) {
198
- $ cache ->set ('endtime ' , time ());
199
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
200
- return $ res ;
201
- }
202
- $ context = $ res ->unwrap ();
193
+ $ res = $ this ->update_personability ()
194
+ ->and_then (fn () => $ this ->first_question_selector ())
195
+ ->or_else (fn ($ res ) => $ this ->after_error ($ res ));
203
196
204
- $ res = $ this ->first_question_selector ();
205
- if ($ res ->iserr ()) {
206
- $ cache ->set ('endtime ' , time ());
207
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
208
- return $ res ;
209
- }
210
197
$ val = $ res ->unwrap ();
211
198
// If the result contains a single object, this is the question to be returned.
212
199
// Othewise, it contains the updated $context array with the ability and standarderror set in such a way, that the
213
200
// teststrategy will return the correct question (e.g. the question corresponding to mean ability of all students).
214
201
if (is_object ($ val )) {
215
202
return $ res ;
216
203
}
217
- $ this ->context = $ val ;
218
204
219
- $ res = $ this ->add_scale_standarderror ();
220
- if ($ res ->iserr ()) {
221
- $ cache ->set ('endtime ' , time ());
222
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
223
- return $ res ;
224
- }
225
- $ this ->context = $ res ->unwrap ();
226
-
227
- $ res = $ this ->maximumquestionscheck ();
228
- if ($ res ->iserr ()) {
229
- $ cache ->set ('endtime ' , time ());
230
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
231
- return $ res ;
232
- }
233
-
234
- $ res = $ this ->removeplayedquestions ();
235
- if ($ res ->iserr ()) {
236
- $ cache ->set ('endtime ' , time ());
237
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
238
- return $ res ;
239
- }
240
- $ this ->context = $ res ->unwrap ();
241
-
242
- $ res = $ this ->noremainingquestions ();
243
- if ($ res ->iserr ()) {
244
- $ cache ->set ('endtime ' , time ());
245
- $ cache ->set ('catquizerror ' , $ res ->get_status ());
246
- return $ res ;
205
+ try {
206
+ $ this ->add_scale_standarderror ()
207
+ ->and_then (fn () => $ this ->maximumquestionscheck ())
208
+ ->and_then (fn () => $ this ->removeplayedquestions ())
209
+ ->and_then (fn () => $ this ->noremainingquestions ())
210
+ ->and_then (fn () => $ this ->fisherinformation ())
211
+ ->or_else (fn ($ res ) => $ this ->after_error ($ res ))
212
+ ->expect ();
213
+ } catch (Exception $ e ) {
214
+ return $ this ->result ;
247
215
}
248
216
249
- $ this ->context = $ this ->fisherinformation ()->unwrap ();
250
-
251
217
$ res = $ this ->maybereturnpilot ();
252
218
$ val = $ res ->unwrap ();
253
219
// If the value is an object, it is the pilot question that should be returned.
254
220
if (is_object ($ val )) {
255
221
return $ res ;
256
222
}
257
- $ this ->context = $ val ;
258
-
259
- $ this ->context = $ this ->remove_uncalculated ()->unwrap ();
260
223
261
- $ this -> context = $ this -> mayberemovescale ()-> unwrap ();
262
-
263
- $ this -> context = $ this ->last_time_played_penalty ()-> unwrap ();
264
-
265
- $ res = $ this ->filterbystandarderror ();
266
- if ( $ res-> iserr ()) {
267
- $ cache -> set ( ' endtime ' , time () );
268
- $ cache -> set ( ' catquizerror ' , $ res -> get_status ());
269
- return $ res ;
224
+ try {
225
+ $ this -> remove_uncalculated ()
226
+ -> and_then ( fn () => $ this ->mayberemovescale ())
227
+ -> and_then ( fn () => $ this -> last_time_played_penalty ())
228
+ -> and_then ( fn () => $ this ->filterbystandarderror ())
229
+ -> or_else ( fn ( $ res) => $ this -> after_error ( $ res ))
230
+ -> expect ( );
231
+ } catch ( Exception $ e ) {
232
+ return $ this -> result ;
270
233
}
271
234
272
- $ this ->context = $ this ->filterbytestinfo ()->unwrap ();
273
-
274
- $ this ->context = $ this ->filterbyquestionsperscale ()->unwrap ();
275
-
276
- $ result = $ this ->select_question ();
277
-
278
- $ this ->progress ->save ();
279
-
280
- $ this ->update_attemptfeedback ($ context );
281
-
282
- if ($ result ->iserr ()) {
283
- $ cache ->set ('endtime ' , time ());
284
- $ cache ->set ('catquizerror ' , $ result ->get_status ());
285
- return $ result ;
235
+ try {
236
+ $ result = $ this ->filterbytestinfo ()
237
+ ->and_then (fn () => $ this ->filterbyquestionsperscale ())
238
+ ->and_then (fn () => $ this ->select_question ())
239
+ ->and_then (
240
+ function ($ res ) {
241
+ $ this ->progress ->save ();
242
+ $ this ->update_attemptfeedback ($ this ->context );
243
+ return $ res ;
244
+ }
245
+ )
246
+ ->or_else (fn ($ res ) => $ this ->after_error ($ res ))
247
+ ->expect ();
248
+ } catch (Exception $ e ) {
249
+ return $ this ->result ;
286
250
}
287
251
288
252
$ selectedquestion = $ result ->unwrap ();
@@ -304,6 +268,15 @@ public function return_next_testitem(array $context) {
304
268
return result::ok ($ selectedquestion );
305
269
}
306
270
271
+ private function after_error ($ result ) {
272
+ $ this ->progress ->save ();
273
+ $ this ->update_attemptfeedback ($ this ->context );
274
+ $ this ->cache ->set ('endtime ' , time ());
275
+ $ this ->cache ->set ('catquizerror ' , $ result ->get_status ());
276
+ $ this ->result = $ result ;
277
+ return $ result ;
278
+ }
279
+
307
280
/**
308
281
* If true, the check page reload is called before updating the ability.
309
282
*
0 commit comments