ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.assClozeGap.php
Go to the documentation of this file.
1<?php
20
34{
35 public const TYPE_TEXT = 0;
36 public const TYPE_SELECT = 1;
37 public const TYPE_NUMERIC = 2;
38
39 public const TEXTGAP_RATING_CASEINSENSITIVE = "ci";
40 public const TEXTGAP_RATING_CASESENSITIVE = "cs";
41 public const TEXTGAP_RATING_LEVENSHTEIN1 = "l1";
42 public const TEXTGAP_RATING_LEVENSHTEIN2 = "l2";
43 public const TEXTGAP_RATING_LEVENSHTEIN3 = "l3";
44 public const TEXTGAP_RATING_LEVENSHTEIN4 = "l4";
45 public const TEXTGAP_RATING_LEVENSHTEIN5 = "l5";
46
47 private ?Transformation $shuffler = null;
48
49 public int $type;
50
58 public $items;
59
65 public $shuffle;
66
67 private $gap_size = 0;
68
75 public function __construct($a_type)
76 {
77 $this->type = (int) $a_type;
78 $this->items = [];
79 $this->shuffle = true;
80 }
81
85 public function getType(): int
86 {
87 return $this->type;
88 }
89
90 public function isTextGap(): bool
91 {
92 return $this->type === self::TYPE_TEXT;
93 }
94
95 public function isSelectGap(): bool
96 {
97 return $this->type === self::TYPE_SELECT;
98 }
99
100 public function isNumericGap(): bool
101 {
102 return $this->type === self::TYPE_NUMERIC;
103 }
104
112 public function setType($a_type = 0): void
113 {
114 $this->type = $a_type;
115 }
116
120 public function getItems(Transformation $shuffler, ?int $gap_index = null): array
121 {
122 if (!$this->getShuffle()) {
123 return $this->items;
124 }
125
126 if ($gap_index === null) {
127 return $shuffler->transform($this->items);
128 }
129
131 for ($i = -2; $i < $gap_index; $i++) {
133 }
134
135 return $items;
136 }
137
147 public function getItemsRaw(): array
148 {
149 return $this->items;
150 }
151
161 public function getItemCount(): int
162 {
163 return count($this->items);
164 }
165
175 public function addItem($a_item): void
176 {
177 $order = $a_item->getOrder();
178 if (array_key_exists($order, $this->items)) {
179 $newitems = [];
180 for ($i = 0; $i < $order; $i++) {
181 array_push($newitems, $this->items[$i]);
182 }
183 array_push($newitems, $a_item);
184 for ($i = $order, $iMax = count($this->items); $i < $iMax; $i++) {
185 array_push($newitems, $this->items[$i]);
186 }
187 $i = 0;
188 foreach ($newitems as $idx => $item) {
189 $newitems[$idx]->setOrder($i);
190 $i++;
191 }
192 $this->items = $newitems;
193 } else {
194 array_push($this->items, $a_item);
195 }
196 }
197
208 public function setItemPoints($order, $points): void
209 {
210 foreach ($this->items as $key => $item) {
211 if ($item->getOrder() == $order) {
212 $item->setPoints($points);
213 }
214 }
215 }
216
226 public function deleteItem($order): void
227 {
228 if (array_key_exists($order, $this->items)) {
229 unset($this->items[$order]);
230 $order = 0;
231 foreach ($this->items as $key => $item) {
232 $this->items[$key]->setOrder($order);
233 $order++;
234 }
235 }
236 }
237
248 public function setItemLowerBound($order, $bound): void
249 {
250 foreach ($this->items as $key => $item) {
251 if ($item->getOrder() == $order) {
252 $item->setLowerBound($bound);
253 }
254 }
255 }
256
267 public function setItemUpperBound($order, $bound): void
268 {
269 foreach ($this->items as $key => $item) {
270 if ($item->getOrder() == $order) {
271 $item->setUpperBound($bound);
272 }
273 }
274 }
275
286 public function getItem($a_index): ?assAnswerCloze
287 {
288 if (array_key_exists($a_index, $this->items)) {
289 return $this->items[$a_index];
290 } else {
291 return null;
292 }
293 }
294
303 public function clearItems(): void
304 {
305 $this->items = [];
306 }
307
315 public function setShuffle($a_shuffle = true): void
316 {
317 $this->shuffle = (bool) $a_shuffle;
318 }
319
325 public function getShuffle(): bool
326 {
327 return $this->shuffle;
328 }
329
338 public function getMaxWidth(): int
339 {
340 $maxwidth = 0;
341 foreach ($this->items as $item) {
342 if (strlen($item->getAnswertext()) > $maxwidth) {
343 $maxwidth = strlen($item->getAnswertext());
344 }
345 }
346 return $maxwidth;
347 }
348
357 public function getBestSolutionIndexes(): array
358 {
359 $maxpoints = 0;
360 foreach ($this->items as $key => $item) {
361 if ($item->getPoints() > $maxpoints) {
362 $maxpoints = $item->getPoints();
363 }
364 }
365 $keys = [];
366 foreach ($this->items as $key => $item) {
367 if ($item->getPoints() == $maxpoints) {
368 array_push($keys, $key);
369 }
370 }
371 return $keys;
372 }
373
379 public function getBestSolutionOutput(Transformation $shuffler, $combinations = null): string
380 {
381 global $DIC;
382 $lng = $DIC['lng'];
383 switch ($this->getType()) {
384 case self::TYPE_TEXT:
386 $best_solutions = [];
387 if ($combinations !== null && $combinations['best_solution'] === 1) {
388 $points_string_for_key = (string) $combinations['points'];
389 $best_solutions[$points_string_for_key] = [];
390 array_push($best_solutions[$points_string_for_key], $combinations['answer']);
391 } else {
392 foreach ($this->getItems($shuffler) as $answer) {
393 $points_string_for_key = (string) $answer->getPoints();
394 if (isset($best_solutions[$points_string_for_key]) && is_array($best_solutions[$points_string_for_key])) {
395 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
396 } else {
397 $best_solutions[$points_string_for_key] = [];
398 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
399 }
400 }
401 }
402
403 krsort($best_solutions, SORT_NUMERIC);
404 reset($best_solutions);
405 $found = current($best_solutions);
406 return join(" " . $lng->txt("or") . " ", $found);
407 break;
409 $maxpoints = 0;
410 $foundvalue = "";
411 foreach ($this->getItems($shuffler) as $answer) {
412 if ($answer->getPoints() >= $maxpoints) {
413 $maxpoints = $answer->getPoints();
414 $foundvalue = $answer->getAnswertext();
415 }
416 }
417 return $foundvalue;
418 break;
419 default:
420 return "";
421 }
422 }
423
424 public function setGapSize(int $gap_size): void
425 {
426 $this->gap_size = $gap_size;
427 }
428
432 public function getGapSize(): int
433 {
434 return (int) $this->gap_size;
435 }
436
437 public function numericRangeExists(): bool
438 {
439 if ($this->getType() != self::TYPE_NUMERIC) {
440 return false;
441 }
442
443 $math = new EvalMath();
444
445 $item = $this->getItem(0);
446 $lowerBound = $math->evaluate($item->getLowerBound());
447 $upperBound = $math->evaluate($item->getUpperBound());
448 $preciseValue = $math->evaluate($item->getAnswertext());
449
450 if ($lowerBound < $preciseValue || $upperBound > $preciseValue) {
451 return true;
452 }
453
454 return false;
455 }
456}
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class for cloze question gaps.
const TEXTGAP_RATING_CASESENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN1
const TEXTGAP_RATING_LEVENSHTEIN5
getBestSolutionOutput(Transformation $shuffler, $combinations=null)
setItemLowerBound($order, $bound)
Sets the lower bound for a given item.
deleteItem($order)
Deletes an item at a given index.
getBestSolutionIndexes()
Returns the indexes of the best solutions for the gap.
const TEXTGAP_RATING_CASEINSENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN4
getItemCount()
Gets the item count.
setItemPoints($order, $points)
Sets the points for a given item.
getShuffle()
Gets the shuffle state of the items.
clearItems()
Removes all gap items.
getMaxWidth()
Returns the maximum width of the gap.
setShuffle($a_shuffle=true)
Sets the shuffle state of the items.
Transformation $shuffler
const TEXTGAP_RATING_LEVENSHTEIN2
const TEXTGAP_RATING_LEVENSHTEIN3
setGapSize(int $gap_size)
getItem($a_index)
Gets the item with a given index.
__construct($a_type)
assClozeGap constructor
getItemsRaw()
Gets the items of a cloze gap.
addItem($a_item)
Adds a gap item.
setItemUpperBound($order, $bound)
Sets the upper bound for a given item.
getItems(Transformation $shuffler, ?int $gap_index=null)
setType($a_type=0)
Sets the cloze gap type.
A transformation is a function from one datatype to another.
transform($from)
Perform the transformation.
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26