ILIAS  release_7 Revision v7.30-3-g800a261c036
class.assFormulaQuestionResult.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
11{
13 const RESULT_DEC = 1;
14 const RESULT_FRAC = 2;
15 const RESULT_CO_FRAC = 3;
16
17 private $result;
18 private $range_min;
19 private $range_max;
20 private $tolerance;
21 private $unit;
22 private $formula;
24 private $rating_sign;
26 private $rating_unit;
27 private $points;
28 private $precision;
29 private $result_type;
32
33 private $available_units = array();
34
52 {
53 $this->result = $result;
54 # $this->setRangeMin((is_numeric($range_min)) ? $range_min : NULL);
55 # $this->setRangeMax((is_numeric($range_max)) ? $range_max : NULL);
56 $this->setRangeMin($range_min);
57 $this->setRangeMax($range_max);
58
59
60 $this->tolerance = $tolerance;
61 $this->unit = $unit;
62 $this->formula = $formula;
63 $this->points = $points;
64 $this->precision = $precision;
65 $this->rating_simple = $rating_simple;
66 $this->rating_sign = $rating_sign;
67 $this->rating_value = $rating_value;
68 $this->rating_unit = $rating_unit;
69 $this->result_type = $result_type;
72 }
73
74 public function substituteFormula($variables, $results)
75 {
76 global $DIC;
77 $lng = $DIC['lng'];
78
79 $formula = $this->getFormula();
80
81 if (preg_match_all("/(\\\$r\\d+)/ims", $formula, $matches)) {
82 foreach ($matches[1] as $result) {
83 if (strcmp($result, $this->getResult()) == 0) {
84 ilUtil::sendFailure($lng->txt("errRecursionInResult"));
85 return false;
86 }
87
88 if (is_object($results[$result])) {
89 $formula = str_replace($result, $results[$result]->substituteFormula($variables, $results), $formula);
90 } else {
91 ilUtil::sendFailure($lng->txt("errFormulaQuestion"));
92 return false;
93 }
94 }
95 }
96
97 return "(" . $formula . ")";
98 }
99
100 public function calculateFormula($variables, $results, $question_id = 0, $use_precision = true)
101 {
102 $resultunits = array();
103 if ($question_id > 0) {
104 $resultunits = $this->getAvailableResultUnits($question_id);
105 }
106
107 include_once "./Services/Math/classes/class.ilMath.php";
108 include_once "./Services/Math/classes/class.EvalMath.php";
109 $formula = $this->substituteFormula($variables, $results);
110 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
111 foreach ($matches[1] as $variable) {
112 $varObj = $variables[$variable];
113 if (!is_object($varObj)) {
114 continue;
115 }
116 $value = $varObj->getBaseValue();
117 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $value . ")" . "\\1", $formula);
118 }
119 }
120 $math = new EvalMath();
121 $math->suppress_errors = true;
122
123 $formula = str_replace(",", ".", $formula);
124 $result = $math->evaluate($formula);
125 if (is_object($this->getUnit())) {
126 $result = ilMath::_div($result, $this->getUnit()->getFactor(), 100);
127 }
128
129 // @todo DON'T USE ilMath::_mul() ... bcmul() returns wrong result !!!!
130
131 if ($use_precision == true) {
132 $res = $result * 1;
133 if (is_numeric($this->getPrecision())) {
134 if ($this->getResultType() == self::RESULT_DEC || $this->getResultType() == self::RESULT_NO_SELECTION) {
135 $result = ilMath::_round($res, $this->getPrecision());
136 }
137 }
138 }
139 return $result;
140 }
141
142 public function findValidRandomVariables($variables, $results)
143 {
144 include_once "./Services/Math/classes/class.EvalMath.php";
145 $i = 0;
146 $inRange = false;
147 while ($i < 1000 && !$inRange) {
148 $formula = $this->substituteFormula($variables, $results);
149 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
150 foreach ($matches[1] as $variable) {
151 $varObj = $variables[$variable];
152 if (!is_object($varObj)) {
153 continue;
154 }
155 $varObj->setRandomValue();
156 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
157 }
158 }
159 $math = new EvalMath();
160 $math->suppress_errors = true;
161 $result = $math->evaluate($formula);
162 $inRange = (is_numeric($result)) ? true : false;
163 if ($inRange) {
164 if (is_numeric($this->getRangeMin())) {
165 if ($result < $this->getRangeMinBase()) {
166 $inRange = false;
167 }
168 }
169 if (is_numeric($this->getRangeMax())) {
170 if ($result > $this->getRangeMaxBase()) {
171 $inRange = false;
172 }
173 }
174 }
175 $i++;
176 }
177 }
178
179 public function suggestRange($variables, $results)
180 {
181
182// @todo Check this
183 include_once "./Services/Math/classes/class.EvalMath.php";
184 $range_min = null;
185 $range_max = null;
186 for ($i = 0; $i < 1000; $i++) {
187 $formula = $this->substituteFormula($variables, $results);
188 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
189 foreach ($matches[1] as $variable) {
190 $varObj = $variables[$variable];
191 if (!is_object($varObj)) {
192 continue;
193 }
194 $varObj->setRandomValue();
195 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
196 }
197 }
198 $math = new EvalMath();
199 $math->suppress_errors = true;
200 $result = $math->evaluate($formula);
201 if (($range_min == null) || ($result < $range_min)) {
203 }
204 if (($range_max == null) || ($result > $range_max)) {
206 }
207 }
208 include_once "./Services/Math/classes/class.ilMath.php";
209 if (is_object($this->getUnit())) {
210 $range_min = ilMath::_div($range_min, $this->getUnit()->getFactor());
211 $range_max = ilMath::_div($range_max, $this->getUnit()->getFactor());
212 }
213 $this->setRangeMin(ilMath::_mul($range_min, 1, $this->getPrecision()));
214 $this->setRangeMax(ilMath::_mul($range_max, 1, $this->getPrecision()));
215 }
216
224 public function isCorrect($variables, $results, $value, $unit = null)
225 {
226 // The user did not answer the question ....
227 if ($value === null || 0 == strlen($value)) {
228 return false;
229 }
230 $value = str_replace(' ', '', $value);
231
232 include_once "./Services/Math/classes/class.EvalMath.php";
233 include_once "./Services/Math/classes/class.ilMath.php";
234 $formula = $this->substituteFormula($variables, $results);
235
236 $check_valid_chars = true;
237
238 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
239 foreach ($matches[1] as $variable) {
240 $varObj = $variables[$variable];
241 if (!is_object($varObj)) {
242 continue;
243 }
244
245 if ($varObj->getUnit() != null) {
246 //convert unit and value to baseunit.... because vars could have different units
247 if ($varObj->getUnit()->getBaseUnit() != -1) { #$this->getUnit() != NULL)
248 $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
249 } else {
250 $tmp_value = $varObj->getValue();
251 }
252 } else {
253 $tmp_value = $varObj->getValue();
254 }
255
256 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
257 }
258 }
259
260 $math = new EvalMath();
261 $math->suppress_errors = true;
262 $result = $math->evaluate($formula); // baseunit-result!!
263 $resultWithRespectedUnit = $result;
264
265 if (is_object($this->getUnit())) {
266 //there is a "fix" result_unit defined!
267
268 // if expected resultunit != baseunit convert to "fix" result_unit
269 if ($this->getUnit()->getBaseUnit() != -1) {
270 $resultWithRespectedUnit = ilMath::_div($result, $this->getUnit()->getFactor());
271 }
272 } elseif ($this->getUnit() == null && $unit != null) {
273 // there is no "fix" result_unit defined, but the user has selected a unit ...
274 // so .... there are "available resultunits" in multi-selectbox selected
275 // -> check if selected user-unit is baseunit
276 if ($unit->getFactor() != 1 && strlen(trim($unit->getFactor())) != 1) {
277 // result is already calculated to baseunit.... -> get correct precision..
278 $resultWithRespectedUnit = ilMath::_div($result, $unit->getFactor());
279 }
280 }
281
282 // check for valid chars ("0-9",",|.|/","0-9","e|E","+|-","0-9")
283 $has_valid_chars = preg_match("/^-?([0-9]*)(,|\\.|\\/){0,1}([0-9]*)([eE][\\+|-]([0-9])+)?$/", $value, $matches);
284 if (!$has_valid_chars) {
285 $check_valid_chars = false;
286 } elseif (
287 (isset($matches[2]) && $matches[2] == '/') &&
288 (isset($matches[4]) && strtolower($matches[4]) == "e") &&
289 (!isset($matches[1]) || !strlen($matches[1]) || !isset($matches[3]) || !strlen($matches[3]) || $matches[3] == 0)) {
290 $check_valid_chars = false;
291 }
292
293 // result_type extension
294 switch ($this->getResultType()) {
296 if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
297 $exp_val = $value;
298 $frac_value = str_replace(',', '.', $exp_val);
299 } else {
300 $frac_value = $value;
301 }
302
303 if (substr_count($value, '/') >= 1) {
304 $check_fraction = false;
305 } else {
306 $check_fraction = true;
307 }
308 break;
309
312 $exp_val = explode('/', $value);
313 if (count($exp_val) == 1) {
314 $frac_value = ilMath::_div($exp_val[0], 1);
315
316 if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
317 $check_fraction = true;
318 } else {
319 $check_fraction = false;
320 }
321 } else {
322 try {
323 $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
324 } catch (ilMathDivisionByZeroException $ex) {
325 if ($result) {
326 return false;
327 } else {
328 return true;
329 }
330 }
331 $frac_value = str_replace(',', '.', $frac_value);
332
333 if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
334 $check_fraction = true;
335 }
336
338 if (!self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
339 $check_fraction = false;
340 }
341 }
342 }
343
344 if (substr_count($value, '.') >= 1 || substr_count($value, ',') >= 1) {
345 $check_fraction = false;
346 }
347 break;
348
350 default:
351 if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
352 $frac_value = str_replace(',', '.', $value);
353 } elseif (substr_count($value, '/') == 1) {
354 $exp_val = explode('/', $value);
355 try {
356 $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
357 } catch (ilMathDivisionByZeroException $ex) {
358 if ($result) {
359 return false;
360 } else {
361 return true;
362 }
363 }
364 } else {
365 $frac_value = $value;
366 }
367
368 $check_fraction = true;
369 break;
370 }
371
372 if (is_object($unit)) {
373 if (isset($frac_value)) {
374 $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
375 }
376 }
377
378 $frac_value = ilMath::_round($frac_value, $this->getPrecision());
379 $resultWithRespectedUnit = ilMath::_round($resultWithRespectedUnit, $this->getPrecision());
380
381 $checkvalue = false;
382 if (isset($frac_value)) {
383 if ($this->isInTolerance($frac_value, $resultWithRespectedUnit, $this->getTolerance())) {
384 $checkvalue = true;
385 }
386 } else {
387 if ($this->isInTolerance($value, $resultWithRespectedUnit, $this->getTolerance())) {
388 $checkvalue = true;
389 }
390 }
391
392 $checkunit = true;
393 if (is_object($this->getUnit())) {
394 if (is_object($unit)) {
395 if ($unit->getId() != $this->getUnit()->getId()) {
396 $checkunit = false;
397 }
398 }
399 }
400 return $checkvalue && $checkunit && $check_fraction && $check_valid_chars;
401 }
402
403 protected function isInTolerance($user_answer, $expected, $tolerated_percentage)
404 {
405 $user_answer = ilMath::_mul($user_answer, 1, $this->getPrecision());
406 $tolerance_abs = abs(ilMath::_div(ilMath::_mul($tolerated_percentage, $expected, 100), 100));
407 $lower_boundary = ilMath::_sub($expected, $tolerance_abs);
408 $upper_boundary = ilMath::_add($expected, $tolerance_abs);
409
410 return $lower_boundary <= $user_answer
411 && $user_answer <= $upper_boundary;
412 }
413
414 protected function checkSign($v1, $v2)
415 {
416 if ((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0))) {
417 return true;
418 } else {
419 return false;
420 }
421 }
422
423 public function getReachedPoints($variables, $results, $value, $unit, $units)
424 {
425 global $DIC;
426 $ilLog = $DIC['ilLog'];
427 if ($this->getRatingSimple()) {
428 if ($this->isCorrect($variables, $results, $value, $units[$unit])) {
429 return $this->getPoints();
430 } else {
431 return 0;
432 }
433 } else {
434 $points = 0;
435 include_once "./Services/Math/classes/class.EvalMath.php";
436 include_once "./Services/Math/classes/class.ilMath.php";
437 $formula = $this->substituteFormula($variables, $results);
438
439 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
440 foreach ($matches[1] as $variable) {
441 $varObj = $variables[$variable];
442 if (!is_object($varObj)) {
443 continue;
444 }
445 if ($varObj->getUnit() != null) {
446 //convert unit and value to baseunit
447 if ($varObj->getUnit()->getBaseUnit() != -1) {
448 $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
449 } else {
450 $tmp_value = $varObj->getValue();
451 }
452 } else {
453 $tmp_value = $varObj->getValue();
454 }
455 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
456 }
457 }
458
459 $math = new EvalMath();
460 $math->suppress_errors = true;
461 $result = $math->evaluate($formula);
462
463 // result_type extension
464 switch ($this->getResultType()) {
466 if ((substr_count($value, '.') == 1) || (substr_count($value, ',') == 1)) {
467 $exp_val = $value;
468 $frac_value = str_replace(',', '.', $exp_val);
469 } else {
470 $frac_value = $value;
471 }
472 $check_fraction = true;
473 break;
475 $exp_val = explode('/', $value);
476 if (count($exp_val) == 1) {
477 $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
478 if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
479 $check_fraction = true;
480 } else {
481 $check_fraction = false;
482 }
483 } else {
484 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
485 if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
486 $check_fraction = true;
487 }
488 }
489 break;
491 $exp_val = explode('/', $value);
492 if (count($exp_val) == 1) {
493 $check_fraction = false;
494 } else {
495 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
496 if (self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
497 $check_fraction = true;
498 }
499 }
500 break;
502 default:
503 $check_fraction = true;
504 break;
505 }
506
507 // result unit!!
508 if (is_object($this->getUnit())) {
509 // if expected resultunit != baseunit convert to resultunit
510 if ($this->getUnit()->getBaseUnit() != -1) {
511 $result = ilMath::_div($result, $this->getUnit()->getFactor(), $this->getPrecision());
512 } else {
513 //if resultunit == baseunit calculate to get correct precision
514 $result = ilMath::_mul($result, $this->getUnit()->getFactor(), $this->getPrecision());
515 }
516 }
517
518 if (is_object($unit)) {
519 if (isset($frac_value)) {
520 $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
521 }
522 }
523
524 if ($this->checkSign($result, $value)) {
525 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
526 }
527
528 if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
529 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
530 }
531 if (is_object($this->getUnit())) {
532 $base1 = $units[$unit];
533 if (is_object($base1)) {
534 $base1 = $units[$base1->getBaseUnit()];
535 }
536 $base2 = $units[$this->getUnit()->getBaseUnit()];
537 if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
538 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
539 }
540 }
541 return $points;
542 }
543 }
544
545 public function getResultInfo($variables, $results, $value, $unit, $units)
546 {
547 if ($this->getRatingSimple()) {
548 if ($this->isCorrect($variables, $results, $value, $units[$unit])) {
549 return array("points" => $this->getPoints());
550 } else {
551 return array("points" => 0);
552 }
553 } else {
554 include_once "./Services/Math/classes/class.EvalMath.php";
555 include_once "./Services/Math/classes/class.ilMath.php";
556 $totalpoints = 0;
557 $formula = $this->substituteFormula($variables, $results);
558 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
559 foreach ($matches[1] as $variable) {
560 $varObj = $variables[$variable];
561 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
562 }
563 }
564 $math = new EvalMath();
565 $math->suppress_errors = true;
566 $result = $math->evaluate($formula);
567 if (is_object($this->getUnit())) {
568 $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
569 }
570 if (is_object($unit)) {
571 $value = ilMath::_mul($value, $unit->getFactor(), 100);
572 } else {
573 }
574 $details = array();
575 if ($this->checkSign($result, $value)) {
576 $points = ilMath::_mul($this->getPoints(), $this->getRatingSign() / 100);
577 $totalpoints += $points;
578 $details['sign'] = $points;
579 }
580 if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
581 $points = ilMath::_mul($this->getPoints(), $this->getRatingValue() / 100);
582 $totalpoints += $points;
583 $details['value'] = $points;
584 }
585 if (is_object($this->getUnit())) {
586 $base1 = $units[$unit];
587 if (is_object($base1)) {
588 $base1 = $units[$base1->getBaseUnit()];
589 }
590 $base2 = $units[$this->getUnit()->getBaseUnit()];
591 if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
592 $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit() / 100);
593 $totalpoints += $points;
594 $details['unit'] = $points;
595 }
596 }
597 $details['points'] = $totalpoints;
598 return $details;
599 }
600 }
601
602 /************************************
603 * Getter and Setter
604 ************************************/
605
606 public function setResult($result)
607 {
608 $this->result = $result;
609 }
610
611 public function getResult()
612 {
613 return $this->result;
614 }
615
616 public function setRangeMin($range_min)
617 {
618 // include_once "./Services/Math/classes/class.EvalMath.php";
619 // $math = new EvalMath();
620 // $math->suppress_errors = TRUE;
621 // $result = $math->evaluate($range_min);
622 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
623 // $this->range_min = $val;
624
625 include_once "./Services/Math/classes/class.EvalMath.php";
626 $math = new EvalMath();
627 $math->suppress_errors = true;
628 $result = $math->evaluate($range_min);
629 $this->range_min = $result;
630 }
631
632 public function getRangeMin()
633 {
634 return $this->range_min;
635 }
636
637 public function getRangeMinBase()
638 {
639 if (is_numeric($this->getRangeMin())) {
640 if (is_object($this->getUnit())) {
641 include_once "./Services/Math/classes/class.ilMath.php";
642 return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
643 }
644 }
645 return $this->getRangeMin();
646 }
647
648 public function setRangeMax($range_max)
649 {
650 // include_once "./Services/Math/classes/class.EvalMath.php";
651 // $math = new EvalMath();
652 // $math->suppress_errors = TRUE;
653 // $result = $math->evaluate($range_max);
654 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
655 // $this->range_max = $val;
656
657 include_once "./Services/Math/classes/class.EvalMath.php";
658 $math = new EvalMath();
659 $math->suppress_errors = true;
660 $result = $math->evaluate($range_max);
661 $this->range_max = $result;
662 }
663
664 public function getRangeMax()
665 {
666 return $this->range_max;
667 }
668
669 public function getRangeMaxBase()
670 {
671 if (is_numeric($this->getRangeMax())) {
672 if (is_object($this->getUnit())) {
673 include_once "./Services/Math/classes/class.ilMath.php";
674 return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
675 }
676 }
677 return $this->getRangeMax();
678 }
679
680 public function setTolerance($tolerance)
681 {
682 $this->tolerance = $tolerance;
683 }
684
685 public function getTolerance()
686 {
687 return $this->tolerance;
688 }
689
690 public function setUnit($unit)
691 {
692 $this->unit = $unit;
693 }
694
695 public function getUnit()
696 {
697 return $this->unit;
698 }
699
700 public function setFormula($formula)
701 {
702 $this->formula = $formula;
703 }
704
705 public function getFormula()
706 {
707 return $this->formula;
708 }
709
710 public function setPoints($points)
711 {
712 $this->points = $points;
713 }
714
715 public function getPoints()
716 {
717 return $this->points;
718 }
719
721 {
722 $this->rating_simple = $rating_simple;
723 }
724
725 public function getRatingSimple()
726 {
728 }
729
731 {
732 $this->rating_sign = $rating_sign;
733 }
734
735 public function getRatingSign()
736 {
737 return $this->rating_sign;
738 }
739
741 {
742 $this->rating_value = $rating_value;
743 }
744
745 public function getRatingValue()
746 {
747 return $this->rating_value;
748 }
749
751 {
752 $this->rating_unit = $rating_unit;
753 }
754
755 public function getRatingUnit()
756 {
757 return $this->rating_unit;
758 }
759
760 public function setPrecision($precision)
761 {
762 $this->precision = $precision;
763 }
764
765 public function getPrecision()
766 {
767 return (int) $this->precision;
768 }
769
770 public function setResultType($a_result_type)
771 {
772 $this->result_type = $a_result_type;
773 }
774
775 public function getResultType()
776 {
777 return (int) $this->result_type;
778 }
779
781 {
782 $this->range_max_txt = $range_max_txt;
783 }
784
785 public function getRangeMaxTxt()
786 {
788 }
789
791 {
792 $this->range_min_txt = $range_min_txt;
793 }
794
795 public function getRangeMinTxt()
796 {
798 }
799
800 public static function getResultTypeByQstId($a_qst_id, $a_result)
801 {
802 global $DIC;
803 $ilDB = $DIC['ilDB'];
804
805 $res = $ilDB->queryF(
806 '
807 SELECT result_type
808 FROM il_qpl_qst_fq_res
809 WHERE question_fi = %s
810 AND result = %s',
811 array('integer', 'text'),
812 array($a_qst_id, $a_result)
813 );
814
815 $row = $ilDB->fetchAssoc($res);
816
817 return $row['result_type'];
818 }
819
820 public static function isCoprimeFraction($numerator, $denominator)
821 {
822 $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
823
824 return $gcd == 1 ? true : false;
825 }
826
827 public static function convertDecimalToCoprimeFraction($decimal_value, $tolerance = 1.e-9)
828 {
829 if (empty($decimal_value)) {
830 return '';
831 }
832
833 $to_string = (string) $decimal_value;
834 $is_negative = strpos($to_string, '-') === 0;
835 if ($is_negative) {
836 $decimal_value = substr($decimal_value, 1);
837 }
838 $h1 = 1;
839 $h2 = 0;
840 $k1 = 0;
841 $k2 = 1;
842 $b = 1 / $decimal_value;
843 do {
844 $b = 1 / $b;
845 $a = floor($b);
846 $aux = $h1;
847 $h1 = $a * $h1 + $h2;
848 $h2 = $aux;
849 $aux = $k1;
850 $k1 = $a * $k1 + $k2;
851 $k2 = $aux;
852 $b = $b - $a;
853 } while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ($k1 < 0 || $b < 0));
854 if ($k1 == 1) {
855 $result = $h1;
856 $checkResult = $h1;
857 } else {
858 $result = "$h1/$k1";
859 $checkResult = ($h1 / $k1);
860 }
861 if ($is_negative) {
862 $result = '-' . $result;
863 $checkResult = ($h1 / $k1) * -1;
864 }
865 if ($to_string == $checkResult . '' || $checkResult . '' == $result) {
866 return $result;
867 } else {
868 return array($to_string,$result);
869 }
870 }
871
872 public static function getGreatestCommonDivisor($a, $b)
873 {
874 if ($b > 0) {
876 } else {
877 return $a;
878 }
879 }
880
881
882 public function getAvailableResultUnits($question_id)
883 {
884 global $DIC;
885 $ilDB = $DIC['ilDB'];
886
887 $res = $ilDB->queryF(
888 '
889 SELECT * FROM il_qpl_qst_fq_res_unit
890 WHERE question_fi = %s
891 ORDER BY result',
892 array('integer'),
893 array($question_id)
894 );
895
896
897 while ($row = $ilDB->fetchAssoc($res)) {
898 $this->available_units[$row['result']][] = $row['unit_fi'] ;
899 }
900
902 }
903}
An exception for terminatinating execution or to throw for unit testing.
return true
Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio.
isInTolerance($user_answer, $expected, $tolerated_percentage)
static getResultTypeByQstId($a_qst_id, $a_result)
calculateFormula($variables, $results, $question_id=0, $use_precision=true)
static isCoprimeFraction($numerator, $denominator)
getResultInfo($variables, $results, $value, $unit, $units)
static convertDecimalToCoprimeFraction($decimal_value, $tolerance=1.e-9)
findValidRandomVariables($variables, $results)
getReachedPoints($variables, $results, $value, $unit, $units)
__construct($result, $range_min, $range_max, $tolerance, $unit, $formula, $points, $precision, $rating_simple=true, $rating_sign=33, $rating_value=34, $rating_unit=33, $result_type=0)
assFormulaQuestionResult constructor
isCorrect($variables, $results, $value, $unit=null)
static _mul($left_operand, $right_operand, $scale=50)
static _div($left_operand, $right_operand, $scale=50)
static _sub($left_operand, $right_operand, $scale=50)
static _add($left_operand, $right_operand, $scale=50)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
global $DIC
Definition: goto.php:24
$i
Definition: metadata.php:24
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$results
$lng
foreach($_POST as $key=> $value) $res
global $ilDB