ILIAS  trunk Revision v12.0_alpha-1540-g00f839d5fa1
class.assClozeGap.php
Go to the documentation of this file.
1<?php
2
21
35{
36 public const TYPE_TEXT = 0;
37 public const TYPE_SELECT = 1;
38 public const TYPE_NUMERIC = 2;
39
40 public const TEXTGAP_RATING_CASEINSENSITIVE = "ci";
41 public const TEXTGAP_RATING_CASESENSITIVE = "cs";
42 public const TEXTGAP_RATING_LEVENSHTEIN1 = "l1";
43 public const TEXTGAP_RATING_LEVENSHTEIN2 = "l2";
44 public const TEXTGAP_RATING_LEVENSHTEIN3 = "l3";
45 public const TEXTGAP_RATING_LEVENSHTEIN4 = "l4";
46 public const TEXTGAP_RATING_LEVENSHTEIN5 = "l5";
47
48 private ?Transformation $shuffler = null;
49
50 public int $type;
51
59 public $items;
60
66 public $shuffle;
67
68 private $gap_size = 0;
69
76 public function __construct($a_type)
77 {
78 $this->type = (int) $a_type;
79 $this->items = [];
80 $this->shuffle = true;
81 }
82
86 public function getType(): int
87 {
88 return $this->type;
89 }
90
91 public function isTextGap(): bool
92 {
93 return $this->type === self::TYPE_TEXT;
94 }
95
96 public function isSelectGap(): bool
97 {
98 return $this->type === self::TYPE_SELECT;
99 }
100
101 public function isNumericGap(): bool
102 {
103 return $this->type === self::TYPE_NUMERIC;
104 }
105
113 public function setType($a_type = 0): void
114 {
115 $this->type = $a_type;
116 }
117
121 public function getItems(Transformation $shuffler, ?int $gap_index = null): array
122 {
123 if (!$this->getShuffle()) {
124 return $this->items;
125 }
126
127 if ($gap_index === null) {
128 return $shuffler->transform($this->items);
129 }
130
132 for ($i = -2; $i < $gap_index; $i++) {
134 }
135
136 return $items;
137 }
138
148 public function getItemsRaw(): array
149 {
150 return $this->items;
151 }
152
162 public function getItemCount(): int
163 {
164 return count($this->items);
165 }
166
176 public function addItem($a_item): void
177 {
178 $order = $a_item->getOrder();
179 if (array_key_exists($order, $this->items)) {
180 $newitems = [];
181 for ($i = 0; $i < $order; $i++) {
182 array_push($newitems, $this->items[$i]);
183 }
184 array_push($newitems, $a_item);
185 for ($i = $order, $iMax = count($this->items); $i < $iMax; $i++) {
186 array_push($newitems, $this->items[$i]);
187 }
188 $i = 0;
189 foreach ($newitems as $idx => $item) {
190 $newitems[$idx]->setOrder($i);
191 $i++;
192 }
193 $this->items = $newitems;
194 } else {
195 array_push($this->items, $a_item);
196 }
197 }
198
209 public function setItemPoints($order, $points): void
210 {
211 foreach ($this->items as $key => $item) {
212 if ($item->getOrder() == $order) {
213 $item->setPoints($points);
214 }
215 }
216 }
217
227 public function deleteItem($order): void
228 {
229 if (array_key_exists($order, $this->items)) {
230 unset($this->items[$order]);
231 $order = 0;
232 foreach ($this->items as $key => $item) {
233 $this->items[$key]->setOrder($order);
234 $order++;
235 }
236 }
237 }
238
249 public function setItemLowerBound($order, $bound): void
250 {
251 foreach ($this->items as $key => $item) {
252 if ($item->getOrder() == $order) {
253 $item->setLowerBound($bound);
254 }
255 }
256 }
257
268 public function setItemUpperBound($order, $bound): void
269 {
270 foreach ($this->items as $key => $item) {
271 if ($item->getOrder() == $order) {
272 $item->setUpperBound($bound);
273 }
274 }
275 }
276
287 public function getItem($a_index): ?assAnswerCloze
288 {
289 if (array_key_exists($a_index, $this->items)) {
290 return $this->items[$a_index];
291 } else {
292 return null;
293 }
294 }
295
304 public function clearItems(): void
305 {
306 $this->items = [];
307 }
308
316 public function setShuffle($a_shuffle = true): void
317 {
318 $this->shuffle = (bool) $a_shuffle;
319 }
320
326 public function getShuffle(): bool
327 {
328 return $this->shuffle;
329 }
330
339 public function getMaxWidth(): int
340 {
341 $maxwidth = 0;
342 foreach ($this->items as $item) {
343 if (strlen($item->getAnswertext()) > $maxwidth) {
344 $maxwidth = strlen($item->getAnswertext());
345 }
346 }
347 return $maxwidth;
348 }
349
358 public function getBestSolutionIndexes(): array
359 {
360 $maxpoints = 0;
361 foreach ($this->items as $key => $item) {
362 if ($item->getPoints() > $maxpoints) {
363 $maxpoints = $item->getPoints();
364 }
365 }
366 $keys = [];
367 foreach ($this->items as $key => $item) {
368 if ($item->getPoints() == $maxpoints) {
369 array_push($keys, $key);
370 }
371 }
372 return $keys;
373 }
374
380 public function getBestSolutionOutput(Transformation $shuffler, $combinations = null): string
381 {
382 global $DIC;
383 $lng = $DIC['lng'];
384 switch ($this->getType()) {
385 case self::TYPE_TEXT:
387 $best_solutions = [];
388 if ($combinations !== null && $combinations['best_solution'] === 1) {
389 $points_string_for_key = (string) $combinations['points'];
390 $best_solutions[$points_string_for_key] = [];
391 array_push($best_solutions[$points_string_for_key], $combinations['answer']);
392 } else {
393 foreach ($this->getItems($shuffler) as $answer) {
394 $points_string_for_key = (string) $answer->getPoints();
395 if (isset($best_solutions[$points_string_for_key]) && is_array($best_solutions[$points_string_for_key])) {
396 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
397 } else {
398 $best_solutions[$points_string_for_key] = [];
399 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
400 }
401 }
402 }
403
404 krsort($best_solutions, SORT_NUMERIC);
405 reset($best_solutions);
406 $found = current($best_solutions);
407 return join(" " . $lng->txt("or") . " ", $found);
408 break;
410 $maxpoints = 0;
411 $foundvalue = "";
412 foreach ($this->getItems($shuffler) as $answer) {
413 if ($answer->getPoints() >= $maxpoints) {
414 $maxpoints = $answer->getPoints();
415 $foundvalue = $answer->getAnswertext();
416 }
417 }
418 return $foundvalue;
419 break;
420 default:
421 return "";
422 }
423 }
424
425 public function setGapSize(int $gap_size): void
426 {
427 $this->gap_size = $gap_size;
428 }
429
433 public function getGapSize(): int
434 {
435 return (int) $this->gap_size;
436 }
437
438 public function numericRangeExists(): bool
439 {
440 if ($this->getType() != self::TYPE_NUMERIC) {
441 return false;
442 }
443
444 $math = new EvalMath();
445
446 $item = $this->getItem(0);
447 $lowerBound = $math->evaluate($item->getLowerBound());
448 $upperBound = $math->evaluate($item->getUpperBound());
449 $preciseValue = $math->evaluate($item->getAnswertext());
450
451 if ($lowerBound < $preciseValue || $upperBound > $preciseValue) {
452 return true;
453 }
454
455 return false;
456 }
457}
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:26
global $DIC
Definition: shib_login.php:26