ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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
264 $resultWithRespectedUnit = ilMath::_round($result, $this->getPrecision());
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(), $this->getPrecision());
271 } else {
272 //if resultunit == baseunit calculate to get correct precision
273 $resultWithRespectedUnit = ilMath::_mul($result, 1, $this->getPrecision());
274 }
275 } elseif ($this->getUnit() == null && $unit != null) {
276 // there is no "fix" result_unit defined, but the user has selected a unit ...
277 // so .... there are "available resultunits" in multi-selectbox selected
278 // -> check if selected user-unit is baseunit
279 if ($unit->getFactor() == 1 && strlen(trim($unit->getFactor())) == 1) {
280 // result is already calculated to baseunit.... -> get correct precision..
281 $resultWithRespectedUnit = ilMath::_mul($result, 1, $this->getPrecision());
282 } else {
283 $resultWithRespectedUnit = ilMath::_div($result, $unit->getFactor(), $this->getPrecision());
284 }
285 }
286
287 // check for valid chars ("0-9",",|.|/","0-9","e|E","+|-","0-9")
288 $has_valid_chars = preg_match("/^-?([0-9]*)(,|\\.|\\/){0,1}([0-9]*)([eE][\\+|-]([0-9])+)?$/", $value, $matches);
289 if (!$has_valid_chars) {
290 $check_valid_chars = false;
291 } elseif (
292 (isset($matches[2]) && $matches[2] == '/') &&
293 (isset($matches[4]) && strtolower($matches[4]) == "e") &&
294 (!isset($matches[1]) || !strlen($matches[1]) || !isset($matches[3]) || !strlen($matches[3]) || $matches[3] == 0)) {
295 $check_valid_chars = false;
296 }
297 // result_type extension
298 switch ($this->getResultType()) {
300 if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
301 $exp_val = $value;
302 $frac_value = str_replace(',', '.', $exp_val);
303 } else {
304 $frac_value = $value;
305 }
306
307 $frac_value = ilMath::_round($frac_value, $this->getPrecision());
308
309 if (substr_count($value, '/') >= 1) {
310 $check_fraction = false;
311 } else {
312 $check_fraction = true;
313 }
314 break;
315
318 $exp_val = explode('/', $value);
319 if (count($exp_val) == 1) {
320 $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
321 if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
322 $check_fraction = true;
323 } else {
324 $check_fraction = false;
325 }
326 } else {
327 try {
328 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
329 } catch (ilMathDivisionByZeroException $ex) {
330 if ($result) {
331 return false;
332 } else {
333 return true;
334 }
335 }
336 $frac_value = str_replace(',', '.', $frac_value);
337
338 if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
339 $check_fraction = true;
340 }
341
343 if (!self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
344 $check_fraction = false;
345 }
346 }
347 }
348
349 if (substr_count($value, '.') >= 1 || substr_count($value, ',') >= 1) {
350 $check_fraction = false;
351 }
352 break;
353
355 default:
356 if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
357 $frac_value = str_replace(',', '.', $value);
358 } elseif (substr_count($value, '/') == 1) {
359 $exp_val = explode('/', $value);
360 try {
361 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
362 } catch (ilMathDivisionByZeroException $ex) {
363 if ($result) {
364 return false;
365 } else {
366 return true;
367 }
368 }
369 } else {
370 $frac_value = $value;
371 }
372 $frac_value = ilMath::_round($frac_value, $this->getPrecision());
373 $check_fraction = true;
374 break;
375 }
376
377 if (is_object($unit)) {
378 if (isset($frac_value)) {
379 $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
380 }
381 }
382
383 $checkvalue = false;
384 if (isset($frac_value)) {
385 if ($this->isInTolerance($frac_value, $resultWithRespectedUnit, $this->getTolerance())) {
386 $checkvalue = true;
387 }
388 } else {
389 if ($this->isInTolerance($value, $resultWithRespectedUnit, $this->getTolerance())) {
390 $checkvalue = true;
391 }
392 }
393
394 $checkunit = true;
395 if (is_object($this->getUnit())) {
396 if (is_object($unit)) {
397 if ($unit->getId() != $this->getUnit()->getId()) {
398 $checkunit = false;
399 }
400 }
401 }
402 return $checkvalue && $checkunit && $check_fraction && $check_valid_chars;
403 }
404
405 protected function isInTolerance($v1, $v2, $p)
406 {
407 include_once "./Services/Math/classes/class.ilMath.php";
408 $v1 = ilMath::_mul($v1, 1, $this->getPrecision());
409 $b1 = ilMath::_sub($v2, abs(ilMath::_div(ilMath::_mul($p, $v2, 100), 100)), $this->getPrecision());
410 $b2 = ilMath::_add($v2, abs(ilMath::_div(ilMath::_mul($p, $v2, 100), 100)), $this->getPrecision());
411 if (($b1 <= $v1) && ($b2 >= $v1)) {
412 return true;
413 } else {
414 return false;
415 }
416 }
417
418 protected function checkSign($v1, $v2)
419 {
420 if ((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0))) {
421 return true;
422 } else {
423 return false;
424 }
425 }
426
427 public function getReachedPoints($variables, $results, $value, $unit, $units)
428 {
429 global $DIC;
430 $ilLog = $DIC['ilLog'];
431 if ($this->getRatingSimple()) {
432 if ($this->isCorrect($variables, $results, $value, $units[$unit])) {
433 return $this->getPoints();
434 } else {
435 return 0;
436 }
437 } else {
438 $points = 0;
439 include_once "./Services/Math/classes/class.EvalMath.php";
440 include_once "./Services/Math/classes/class.ilMath.php";
441 $formula = $this->substituteFormula($variables, $results);
442
443 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
444 foreach ($matches[1] as $variable) {
445 $varObj = $variables[$variable];
446 if (!is_object($varObj)) {
447 continue;
448 }
449 if ($varObj->getUnit() != null) {
450 //convert unit and value to baseunit
451 if ($varObj->getUnit()->getBaseUnit() != -1) {
452 $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
453 } else {
454 $tmp_value = $varObj->getValue();
455 }
456 } else {
457 $tmp_value = $varObj->getValue();
458 }
459 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
460 }
461 }
462
463 $math = new EvalMath();
464 $math->suppress_errors = true;
465 $result = $math->evaluate($formula);
466
467 // result_type extension
468 switch ($this->getResultType()) {
470 if ((substr_count($value, '.') == 1) || (substr_count($value, ',') == 1)) {
471 $exp_val = $value;
472 $frac_value = str_replace(',', '.', $exp_val);
473 } else {
474 $frac_value = $value;
475 }
476 $check_fraction = true;
477 break;
479 $exp_val = explode('/', $value);
480 if (count($exp_val) == 1) {
481 $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
482 if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
483 $check_fraction = true;
484 } else {
485 $check_fraction = false;
486 }
487 } else {
488 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
489 if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
490 $check_fraction = true;
491 }
492 }
493 break;
495 $exp_val = explode('/', $value);
496 if (count($exp_val) == 1) {
497 $check_fraction = false;
498 } else {
499 $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
500 if (self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
501 $check_fraction = true;
502 }
503 }
504 break;
506 default:
507 $check_fraction = true;
508 break;
509 }
510
511 // result unit!!
512 if (is_object($this->getUnit())) {
513 // if expected resultunit != baseunit convert to resultunit
514 if ($this->getUnit()->getBaseUnit() != -1) {
515 $result = ilMath::_div($result, $this->getUnit()->getFactor(), $this->getPrecision());
516 } else {
517 //if resultunit == baseunit calculate to get correct precision
518 $result = ilMath::_mul($result, $this->getUnit()->getFactor(), $this->getPrecision());
519 }
520 }
521
522 if (is_object($unit)) {
523 if (isset($frac_value)) {
524 $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
525 }
526 }
527
528 if ($this->checkSign($result, $value)) {
529 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
530 }
531 if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
532 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
533 }
534 if (is_object($this->getUnit())) {
535 $base1 = $units[$unit];
536 if (is_object($base1)) {
537 $base1 = $units[$base1->getBaseUnit()];
538 }
539 $base2 = $units[$this->getUnit()->getBaseUnit()];
540 if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
541 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
542 }
543 }
544 return $points;
545 }
546 }
547
548 public function getResultInfo($variables, $results, $value, $unit, $units)
549 {
550 if ($this->getRatingSimple()) {
551 if ($this->isCorrect($variables, $results, $value, $units[$unit])) {
552 return array("points" => $this->getPoints());
553 } else {
554 return array("points" => 0);
555 }
556 } else {
557 include_once "./Services/Math/classes/class.EvalMath.php";
558 include_once "./Services/Math/classes/class.ilMath.php";
559 $totalpoints = 0;
560 $formula = $this->substituteFormula($variables, $results);
561 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
562 foreach ($matches[1] as $variable) {
563 $varObj = $variables[$variable];
564 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
565 }
566 }
567 $math = new EvalMath();
568 $math->suppress_errors = true;
569 $result = $math->evaluate($formula);
570 if (is_object($this->getUnit())) {
571 $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
572 }
573 if (is_object($unit)) {
574 $value = ilMath::_mul($value, $unit->getFactor(), 100);
575 } else {
576 }
577 $details = array();
578 if ($this->checkSign($result, $value)) {
579 $points = ilMath::_mul($this->getPoints(), $this->getRatingSign() / 100);
580 $totalpoints += $points;
581 $details['sign'] = $points;
582 }
583 if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
584 $points = ilMath::_mul($this->getPoints(), $this->getRatingValue() / 100);
585 $totalpoints += $points;
586 $details['value'] = $points;
587 }
588 if (is_object($this->getUnit())) {
589 $base1 = $units[$unit];
590 if (is_object($base1)) {
591 $base1 = $units[$base1->getBaseUnit()];
592 }
593 $base2 = $units[$this->getUnit()->getBaseUnit()];
594 if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
595 $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit() / 100);
596 $totalpoints += $points;
597 $details['unit'] = $points;
598 }
599 }
600 $details['points'] = $totalpoints;
601 return $details;
602 }
603 }
604
605 /************************************
606 * Getter and Setter
607 ************************************/
608
609 public function setResult($result)
610 {
611 $this->result = $result;
612 }
613
614 public function getResult()
615 {
616 return $this->result;
617 }
618
619 public function setRangeMin($range_min)
620 {
621 // include_once "./Services/Math/classes/class.EvalMath.php";
622 // $math = new EvalMath();
623 // $math->suppress_errors = TRUE;
624 // $result = $math->evaluate($range_min);
625 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
626 // $this->range_min = $val;
627
628 include_once "./Services/Math/classes/class.EvalMath.php";
629 $math = new EvalMath();
630 $math->suppress_errors = true;
631 $result = $math->evaluate($range_min);
632 $this->range_min = $result;
633 }
634
635 public function getRangeMin()
636 {
637 return $this->range_min;
638 }
639
640 public function getRangeMinBase()
641 {
642 if (is_numeric($this->getRangeMin())) {
643 if (is_object($this->getUnit())) {
644 include_once "./Services/Math/classes/class.ilMath.php";
645 return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
646 }
647 }
648 return $this->getRangeMin();
649 }
650
651 public function setRangeMax($range_max)
652 {
653 // include_once "./Services/Math/classes/class.EvalMath.php";
654 // $math = new EvalMath();
655 // $math->suppress_errors = TRUE;
656 // $result = $math->evaluate($range_max);
657 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
658 // $this->range_max = $val;
659
660 include_once "./Services/Math/classes/class.EvalMath.php";
661 $math = new EvalMath();
662 $math->suppress_errors = true;
663 $result = $math->evaluate($range_max);
664 $this->range_max = $result;
665 }
666
667 public function getRangeMax()
668 {
669 return $this->range_max;
670 }
671
672 public function getRangeMaxBase()
673 {
674 if (is_numeric($this->getRangeMax())) {
675 if (is_object($this->getUnit())) {
676 include_once "./Services/Math/classes/class.ilMath.php";
677 return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
678 }
679 }
680 return $this->getRangeMax();
681 }
682
683 public function setTolerance($tolerance)
684 {
685 $this->tolerance = $tolerance;
686 }
687
688 public function getTolerance()
689 {
690 return $this->tolerance;
691 }
692
693 public function setUnit($unit)
694 {
695 $this->unit = $unit;
696 }
697
698 public function getUnit()
699 {
700 return $this->unit;
701 }
702
703 public function setFormula($formula)
704 {
705 $this->formula = $formula;
706 }
707
708 public function getFormula()
709 {
710 return $this->formula;
711 }
712
713 public function setPoints($points)
714 {
715 $this->points = $points;
716 }
717
718 public function getPoints()
719 {
720 return $this->points;
721 }
722
724 {
725 $this->rating_simple = $rating_simple;
726 }
727
728 public function getRatingSimple()
729 {
731 }
732
734 {
735 $this->rating_sign = $rating_sign;
736 }
737
738 public function getRatingSign()
739 {
740 return $this->rating_sign;
741 }
742
744 {
745 $this->rating_value = $rating_value;
746 }
747
748 public function getRatingValue()
749 {
750 return $this->rating_value;
751 }
752
754 {
755 $this->rating_unit = $rating_unit;
756 }
757
758 public function getRatingUnit()
759 {
760 return $this->rating_unit;
761 }
762
763 public function setPrecision($precision)
764 {
765 $this->precision = $precision;
766 }
767
768 public function getPrecision()
769 {
770 return (int) $this->precision;
771 }
772
773 public function setResultType($a_result_type)
774 {
775 $this->result_type = $a_result_type;
776 }
777
778 public function getResultType()
779 {
780 return (int) $this->result_type;
781 }
782
784 {
785 $this->range_max_txt = $range_max_txt;
786 }
787
788 public function getRangeMaxTxt()
789 {
791 }
792
794 {
795 $this->range_min_txt = $range_min_txt;
796 }
797
798 public function getRangeMinTxt()
799 {
801 }
802
803 public static function getResultTypeByQstId($a_qst_id, $a_result)
804 {
805 global $DIC;
806 $ilDB = $DIC['ilDB'];
807
808 $res = $ilDB->queryF(
809 '
810 SELECT result_type
811 FROM il_qpl_qst_fq_res
812 WHERE question_fi = %s
813 AND result = %s',
814 array('integer', 'text'),
815 array($a_qst_id, $a_result)
816 );
817
818 $row = $ilDB->fetchAssoc($res);
819
820 return $row['result_type'];
821 }
822
823 public static function isCoprimeFraction($numerator, $denominator)
824 {
825 $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
826
827 return $gcd == 1 ? true : false;
828 }
829
830 public static function convertDecimalToCoprimeFraction($decimal_value, $tolerance = 1.e-9)
831 {
832 $to_string = (string) $decimal_value;
833 $is_negative = strpos($to_string, '-') === 0;
834 if ($is_negative) {
835 $decimal_value = substr($decimal_value, 1);
836 }
837 $h1 = 1;
838 $h2 = 0;
839 $k1 = 0;
840 $k2 = 1;
841 $b = 1 / $decimal_value;
842 do {
843 $b = 1 / $b;
844 $a = floor($b);
845 $aux = $h1;
846 $h1 = $a * $h1 + $h2;
847 $h2 = $aux;
848 $aux = $k1;
849 $k1 = $a * $k1 + $k2;
850 $k2 = $aux;
851 $b = $b - $a;
852 } while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ($k1 < 0 || $b < 0));
853 if ($k1 == 1) {
854 $result = $h1;
855 $checkResult = $h1;
856 } else {
857 $result = "$h1/$k1";
858 $checkResult = ($h1 / $k1);
859 }
860 if ($is_negative) {
861 $result = '-' . $result;
862 $checkResult = ($h1 / $k1) * -1;
863 }
864 if ($to_string == $checkResult . '' || $checkResult . '' == $result) {
865 return $result;
866 } else {
867 return array($to_string,$result);
868 }
869 }
870
871 public static function getGreatestCommonDivisor($a, $b)
872 {
873 if ($b > 0) {
874 return self::getGreatestCommonDivisor($b, $a % $b);
875 } else {
876 return $a;
877 }
878 }
879
880
881 public function getAvailableResultUnits($question_id)
882 {
883 global $DIC;
884 $ilDB = $DIC['ilDB'];
885
886 $res = $ilDB->queryF(
887 '
888 SELECT * FROM il_qpl_qst_fq_res_unit
889 WHERE question_fi = %s
890 ORDER BY result',
891 array('integer'),
892 array($question_id)
893 );
894
895
896 while ($row = $ilDB->fetchAssoc($res)) {
897 $this->available_units[$row['result']][] = $row['unit_fi'] ;
898 }
899
901 }
902}
An exception for terminatinating execution or to throw for unit testing.
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.
$i
Definition: disco.tpl.php:19
$row
global $DIC
Definition: saml.php:7
$lng
foreach($_POST as $key=> $value) $res
global $ilDB
$results
Definition: svg-scanner.php:47