ILIAS  release_7 Revision v7.30-3-g800a261c036
assFormulaQuestionResult Class Reference

Formula Question Result. More...

+ Collaboration diagram for assFormulaQuestionResult:

Public Member Functions

 __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 More...
 
 substituteFormula ($variables, $results)
 
 calculateFormula ($variables, $results, $question_id=0, $use_precision=true)
 
 findValidRandomVariables ($variables, $results)
 
 suggestRange ($variables, $results)
 
 isCorrect ($variables, $results, $value, $unit=null)
 
 getReachedPoints ($variables, $results, $value, $unit, $units)
 
 getResultInfo ($variables, $results, $value, $unit, $units)
 
 setResult ($result)
 
 getResult ()
 
 setRangeMin ($range_min)
 
 getRangeMin ()
 
 getRangeMinBase ()
 
 setRangeMax ($range_max)
 
 getRangeMax ()
 
 getRangeMaxBase ()
 
 setTolerance ($tolerance)
 
 getTolerance ()
 
 setUnit ($unit)
 
 getUnit ()
 
 setFormula ($formula)
 
 getFormula ()
 
 setPoints ($points)
 
 getPoints ()
 
 setRatingSimple ($rating_simple)
 
 getRatingSimple ()
 
 setRatingSign ($rating_sign)
 
 getRatingSign ()
 
 setRatingValue ($rating_value)
 
 getRatingValue ()
 
 setRatingUnit ($rating_unit)
 
 getRatingUnit ()
 
 setPrecision ($precision)
 
 getPrecision ()
 
 setResultType ($a_result_type)
 
 getResultType ()
 
 setRangeMaxTxt ($range_max_txt)
 
 getRangeMaxTxt ()
 
 setRangeMinTxt ($range_min_txt)
 
 getRangeMinTxt ()
 
 getAvailableResultUnits ($question_id)
 

Static Public Member Functions

static getResultTypeByQstId ($a_qst_id, $a_result)
 
static isCoprimeFraction ($numerator, $denominator)
 
static convertDecimalToCoprimeFraction ($decimal_value, $tolerance=1.e-9)
 
static getGreatestCommonDivisor ($a, $b)
 

Data Fields

const RESULT_NO_SELECTION = 0
 
const RESULT_DEC = 1
 
const RESULT_FRAC = 2
 
const RESULT_CO_FRAC = 3
 

Protected Member Functions

 isInTolerance ($user_answer, $expected, $tolerated_percentage)
 
 checkSign ($v1, $v2)
 

Private Attributes

 $result
 
 $range_min
 
 $range_max
 
 $tolerance
 
 $unit
 
 $formula
 
 $rating_simple
 
 $rating_sign
 
 $rating_value
 
 $rating_unit
 
 $points
 
 $precision
 
 $result_type
 
 $range_min_txt
 
 $range_max_txt
 
 $available_units = array()
 

Detailed Description

Formula Question Result.

Author
Helmut Schottmüller helmu.nosp@m.t.sc.nosp@m.hottm.nosp@m.uell.nosp@m.er@ma.nosp@m.c.co.nosp@m.m
Version
Id
class.assFormulaQuestionResult.php 944 2009-11-09 16:11:30Z hschottm

Definition at line 10 of file class.assFormulaQuestionResult.php.

Constructor & Destructor Documentation

◆ __construct()

assFormulaQuestionResult::__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

Parameters
string$resultResult name
double$range_minRange minimum
double$range_maxRange maximum
double$toleranceTolerance of the result in percent
object$unitUnit
string$formulaThe formula to calculate the result
double$pointsThe maximum available points for the result
integer$precisionNumber of decimal places of the value
boolean$rating_simpleUse simple rating (100% if right, 0 % if wrong)
double$rating_signPercentage of rating for the correct sign
double$rating_valuePercentage of rating for the correct value
double$rating_unitPercentage of rating for the correct unit @access public

Definition at line 51 of file class.assFormulaQuestionResult.php.

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 }

References $formula, $points, $precision, $range_max, $range_min, $rating_sign, $rating_simple, $rating_unit, $rating_value, $result, $result_type, $tolerance, $unit, setRangeMax(), setRangeMaxTxt(), setRangeMin(), and setRangeMinTxt().

+ Here is the call graph for this function:

Member Function Documentation

◆ calculateFormula()

assFormulaQuestionResult::calculateFormula (   $variables,
  $results,
  $question_id = 0,
  $use_precision = true 
)

Definition at line 100 of file class.assFormulaQuestionResult.php.

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 }
static _div($left_operand, $right_operand, $scale=50)
$results
foreach($_POST as $key=> $value) $res

References $formula, $res, $result, $results, ilMath\_div(), getAvailableResultUnits(), getPrecision(), getResultType(), getUnit(), and substituteFormula().

+ Here is the call graph for this function:

◆ checkSign()

assFormulaQuestionResult::checkSign (   $v1,
  $v2 
)
protected

Definition at line 414 of file class.assFormulaQuestionResult.php.

415 {
416 if ((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0))) {
417 return true;
418 } else {
419 return false;
420 }
421 }

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ convertDecimalToCoprimeFraction()

static assFormulaQuestionResult::convertDecimalToCoprimeFraction (   $decimal_value,
  $tolerance = 1.e-9 
)
static

Definition at line 827 of file class.assFormulaQuestionResult.php.

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 }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

References Vendor\Package\$a, Vendor\Package\$b, $result, and $tolerance.

Referenced by assFormulaQuestion\getBestSolution(), and assFormulaQuestion\substituteVariables().

+ Here is the caller graph for this function:

◆ findValidRandomVariables()

assFormulaQuestionResult::findValidRandomVariables (   $variables,
  $results 
)

Definition at line 142 of file class.assFormulaQuestionResult.php.

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 }
$i
Definition: metadata.php:24

References $formula, $i, $result, $results, getRangeMax(), getRangeMaxBase(), getRangeMin(), getRangeMinBase(), and substituteFormula().

+ Here is the call graph for this function:

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

Definition at line 882 of file class.assFormulaQuestionResult.php.

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 }
global $DIC
Definition: goto.php:24
global $ilDB

References $available_units, $DIC, $ilDB, and $res.

Referenced by calculateFormula().

+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

Definition at line 705 of file class.assFormulaQuestionResult.php.

706 {
707 return $this->formula;
708 }

References $formula.

Referenced by substituteFormula().

+ Here is the caller graph for this function:

◆ getGreatestCommonDivisor()

static assFormulaQuestionResult::getGreatestCommonDivisor (   $a,
  $b 
)
static

Definition at line 872 of file class.assFormulaQuestionResult.php.

873 {
874 if ($b > 0) {
876 } else {
877 return $a;
878 }
879 }

References Vendor\Package\$a, Vendor\Package\$b, and getGreatestCommonDivisor().

Referenced by getGreatestCommonDivisor(), and isCoprimeFraction().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

Definition at line 715 of file class.assFormulaQuestionResult.php.

716 {
717 return $this->points;
718 }

References $points.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

Definition at line 765 of file class.assFormulaQuestionResult.php.

766 {
767 return (int) $this->precision;
768 }

References $precision.

Referenced by calculateFormula(), getReachedPoints(), isCorrect(), isInTolerance(), and suggestRange().

+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

Definition at line 664 of file class.assFormulaQuestionResult.php.

665 {
666 return $this->range_max;
667 }

References $range_max.

Referenced by findValidRandomVariables(), and getRangeMaxBase().

+ Here is the caller graph for this function:

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

Definition at line 669 of file class.assFormulaQuestionResult.php.

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 }
static _mul($left_operand, $right_operand, $scale=50)

References ilMath\_mul(), getRangeMax(), and getUnit().

Referenced by findValidRandomVariables().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMaxTxt()

assFormulaQuestionResult::getRangeMaxTxt ( )

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

Definition at line 632 of file class.assFormulaQuestionResult.php.

633 {
634 return $this->range_min;
635 }

References $range_min.

Referenced by findValidRandomVariables(), and getRangeMinBase().

+ Here is the caller graph for this function:

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

Definition at line 637 of file class.assFormulaQuestionResult.php.

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 }

References ilMath\_mul(), getRangeMin(), and getUnit().

Referenced by findValidRandomVariables().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMinTxt()

assFormulaQuestionResult::getRangeMinTxt ( )

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

Definition at line 735 of file class.assFormulaQuestionResult.php.

736 {
737 return $this->rating_sign;
738 }

References $rating_sign.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

Definition at line 725 of file class.assFormulaQuestionResult.php.

726 {
728 }

References $rating_simple.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

Definition at line 755 of file class.assFormulaQuestionResult.php.

756 {
757 return $this->rating_unit;
758 }

References $rating_unit.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

Definition at line 745 of file class.assFormulaQuestionResult.php.

746 {
747 return $this->rating_value;
748 }

References $rating_value.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getReachedPoints()

assFormulaQuestionResult::getReachedPoints (   $variables,
  $results,
  $value,
  $unit,
  $units 
)

Definition at line 423 of file class.assFormulaQuestionResult.php.

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 }
isInTolerance($user_answer, $expected, $tolerated_percentage)
isCorrect($variables, $results, $value, $unit=null)

References $DIC, $formula, $points, $result, $results, $unit, ilMath\_div(), ilMath\_mul(), checkSign(), getPoints(), getPrecision(), getRatingSign(), getRatingSimple(), getRatingUnit(), getRatingValue(), getResultType(), getTolerance(), getUnit(), isCorrect(), isInTolerance(), RESULT_CO_FRAC, RESULT_DEC, RESULT_FRAC, RESULT_NO_SELECTION, and substituteFormula().

+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

Definition at line 611 of file class.assFormulaQuestionResult.php.

612 {
613 return $this->result;
614 }

References $result.

Referenced by substituteFormula().

+ Here is the caller graph for this function:

◆ getResultInfo()

assFormulaQuestionResult::getResultInfo (   $variables,
  $results,
  $value,
  $unit,
  $units 
)

Definition at line 545 of file class.assFormulaQuestionResult.php.

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 }

References $formula, $points, $result, $results, $unit, ilMath\_mul(), checkSign(), getPoints(), getRatingSign(), getRatingSimple(), getRatingUnit(), getRatingValue(), getTolerance(), getUnit(), isCorrect(), isInTolerance(), and substituteFormula().

+ Here is the call graph for this function:

◆ getResultType()

assFormulaQuestionResult::getResultType ( )

Definition at line 775 of file class.assFormulaQuestionResult.php.

776 {
777 return (int) $this->result_type;
778 }

References $result_type.

Referenced by calculateFormula(), getReachedPoints(), and isCorrect().

+ Here is the caller graph for this function:

◆ getResultTypeByQstId()

static assFormulaQuestionResult::getResultTypeByQstId (   $a_qst_id,
  $a_result 
)
static

Definition at line 800 of file class.assFormulaQuestionResult.php.

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 }

References $DIC, $ilDB, and $res.

Referenced by assFormulaQuestionGUI\getPreview(), and assFormulaQuestionGUI\getTestOutput().

+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

Definition at line 685 of file class.assFormulaQuestionResult.php.

686 {
687 return $this->tolerance;
688 }

References $tolerance.

Referenced by getReachedPoints(), getResultInfo(), and isCorrect().

+ Here is the caller graph for this function:

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

Definition at line 695 of file class.assFormulaQuestionResult.php.

696 {
697 return $this->unit;
698 }

References $unit.

Referenced by calculateFormula(), getRangeMaxBase(), getRangeMinBase(), getReachedPoints(), getResultInfo(), isCorrect(), and suggestRange().

+ Here is the caller graph for this function:

◆ isCoprimeFraction()

static assFormulaQuestionResult::isCoprimeFraction (   $numerator,
  $denominator 
)
static

Definition at line 820 of file class.assFormulaQuestionResult.php.

821 {
822 $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
823
824 return $gcd == 1 ? true : false;
825 }
return true
Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio.

References getGreatestCommonDivisor(), and true.

+ Here is the call graph for this function:

◆ isCorrect()

assFormulaQuestionResult::isCorrect (   $variables,
  $results,
  $value,
  $unit = null 
)
Parameters
$variablesformula variables containing units
$resultsformula results containing units
$valueuser input value
null$unituser input unit
Returns
bool

Definition at line 224 of file class.assFormulaQuestionResult.php.

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 }

References $formula, $result, $results, $unit, ilMath\_div(), ilMath\_mul(), getPrecision(), getResultType(), getTolerance(), getUnit(), isInTolerance(), RESULT_CO_FRAC, RESULT_DEC, RESULT_FRAC, RESULT_NO_SELECTION, and substituteFormula().

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInTolerance()

assFormulaQuestionResult::isInTolerance (   $user_answer,
  $expected,
  $tolerated_percentage 
)
protected

Definition at line 403 of file class.assFormulaQuestionResult.php.

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 }
static _sub($left_operand, $right_operand, $scale=50)
static _add($left_operand, $right_operand, $scale=50)

References ilMath\_add(), ilMath\_div(), ilMath\_mul(), ilMath\_sub(), and getPrecision().

Referenced by getReachedPoints(), getResultInfo(), and isCorrect().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setFormula()

assFormulaQuestionResult::setFormula (   $formula)

Definition at line 700 of file class.assFormulaQuestionResult.php.

701 {
702 $this->formula = $formula;
703 }

References $formula.

◆ setPoints()

assFormulaQuestionResult::setPoints (   $points)

Definition at line 710 of file class.assFormulaQuestionResult.php.

711 {
712 $this->points = $points;
713 }

References $points.

◆ setPrecision()

assFormulaQuestionResult::setPrecision (   $precision)

Definition at line 760 of file class.assFormulaQuestionResult.php.

761 {
762 $this->precision = $precision;
763 }

References $precision.

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax (   $range_max)

Definition at line 648 of file class.assFormulaQuestionResult.php.

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 }

References $range_max, and $result.

Referenced by __construct(), and suggestRange().

+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt (   $range_max_txt)

Definition at line 780 of file class.assFormulaQuestionResult.php.

781 {
782 $this->range_max_txt = $range_max_txt;
783 }

References $range_max_txt.

Referenced by __construct().

+ Here is the caller graph for this function:

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin (   $range_min)

Definition at line 616 of file class.assFormulaQuestionResult.php.

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 }

References $range_min, and $result.

Referenced by __construct(), and suggestRange().

+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt (   $range_min_txt)

Definition at line 790 of file class.assFormulaQuestionResult.php.

791 {
792 $this->range_min_txt = $range_min_txt;
793 }

References $range_min_txt.

Referenced by __construct().

+ Here is the caller graph for this function:

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign (   $rating_sign)

Definition at line 730 of file class.assFormulaQuestionResult.php.

731 {
732 $this->rating_sign = $rating_sign;
733 }

References $rating_sign.

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple (   $rating_simple)

Definition at line 720 of file class.assFormulaQuestionResult.php.

721 {
722 $this->rating_simple = $rating_simple;
723 }

References $rating_simple.

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit (   $rating_unit)

Definition at line 750 of file class.assFormulaQuestionResult.php.

751 {
752 $this->rating_unit = $rating_unit;
753 }

References $rating_unit.

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue (   $rating_value)

Definition at line 740 of file class.assFormulaQuestionResult.php.

741 {
742 $this->rating_value = $rating_value;
743 }

References $rating_value.

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

Definition at line 606 of file class.assFormulaQuestionResult.php.

607 {
608 $this->result = $result;
609 }

References $result.

◆ setResultType()

assFormulaQuestionResult::setResultType (   $a_result_type)

Definition at line 770 of file class.assFormulaQuestionResult.php.

771 {
772 $this->result_type = $a_result_type;
773 }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

Definition at line 680 of file class.assFormulaQuestionResult.php.

681 {
682 $this->tolerance = $tolerance;
683 }

References $tolerance.

◆ setUnit()

assFormulaQuestionResult::setUnit (   $unit)

Definition at line 690 of file class.assFormulaQuestionResult.php.

691 {
692 $this->unit = $unit;
693 }

References $unit.

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula (   $variables,
  $results 
)

Definition at line 74 of file class.assFormulaQuestionResult.php.

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 }
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$lng

References $DIC, $formula, $lng, $result, $results, getFormula(), getResult(), ilUtil\sendFailure(), and substituteFormula().

Referenced by calculateFormula(), findValidRandomVariables(), getReachedPoints(), getResultInfo(), isCorrect(), substituteFormula(), and suggestRange().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ suggestRange()

assFormulaQuestionResult::suggestRange (   $variables,
  $results 
)

Definition at line 179 of file class.assFormulaQuestionResult.php.

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 }

References $formula, $i, $range_max, $range_min, $result, $results, ilMath\_div(), ilMath\_mul(), getPrecision(), getUnit(), setRangeMax(), setRangeMin(), and substituteFormula().

+ Here is the call graph for this function:

Field Documentation

◆ $available_units

assFormulaQuestionResult::$available_units = array()
private

Definition at line 33 of file class.assFormulaQuestionResult.php.

Referenced by getAvailableResultUnits().

◆ $formula

◆ $points

assFormulaQuestionResult::$points
private

◆ $precision

assFormulaQuestionResult::$precision
private

Definition at line 28 of file class.assFormulaQuestionResult.php.

Referenced by __construct(), getPrecision(), and setPrecision().

◆ $range_max

assFormulaQuestionResult::$range_max
private

◆ $range_max_txt

assFormulaQuestionResult::$range_max_txt
private

Definition at line 31 of file class.assFormulaQuestionResult.php.

Referenced by getRangeMaxTxt(), and setRangeMaxTxt().

◆ $range_min

assFormulaQuestionResult::$range_min
private

◆ $range_min_txt

assFormulaQuestionResult::$range_min_txt
private

Definition at line 30 of file class.assFormulaQuestionResult.php.

Referenced by getRangeMinTxt(), and setRangeMinTxt().

◆ $rating_sign

assFormulaQuestionResult::$rating_sign
private

Definition at line 24 of file class.assFormulaQuestionResult.php.

Referenced by __construct(), getRatingSign(), and setRatingSign().

◆ $rating_simple

assFormulaQuestionResult::$rating_simple
private

◆ $rating_unit

assFormulaQuestionResult::$rating_unit
private

Definition at line 26 of file class.assFormulaQuestionResult.php.

Referenced by __construct(), getRatingUnit(), and setRatingUnit().

◆ $rating_value

assFormulaQuestionResult::$rating_value
private

Definition at line 25 of file class.assFormulaQuestionResult.php.

Referenced by __construct(), getRatingValue(), and setRatingValue().

◆ $result

◆ $result_type

assFormulaQuestionResult::$result_type
private

Definition at line 29 of file class.assFormulaQuestionResult.php.

Referenced by __construct(), and getResultType().

◆ $tolerance

assFormulaQuestionResult::$tolerance
private

◆ $unit

assFormulaQuestionResult::$unit
private

◆ RESULT_CO_FRAC

◆ RESULT_DEC

◆ RESULT_FRAC

◆ RESULT_NO_SELECTION

const assFormulaQuestionResult::RESULT_NO_SELECTION = 0

The documentation for this class was generated from the following file: