ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
assFormulaQuestionResult Class Reference

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V. 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()
 
ilGlobalTemplateInterface $main_tpl
 

Detailed Description

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V.

ILIAS is licensed with the GPL-3.0, see https://www.gnu.org/licenses/gpl-3.0.en.html You should have received a copy of said license along with the source code, too.

If this is not the case or you just want to try ILIAS, you'll find us at: https://www.ilias.de https://github.com/ILIAS-eLearning 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 25 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
mixed$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 public

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

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

68  {
69  global $DIC;
70  $this->main_tpl = $DIC->ui()->mainTemplate();
71  $this->result = $result;
72  # $this->setRangeMin((is_numeric($range_min)) ? $range_min : NULL);
73  # $this->setRangeMax((is_numeric($range_max)) ? $range_max : NULL);
74  $this->setRangeMin($range_min);
75  $this->setRangeMax($range_max);
76 
77 
78  $this->tolerance = $tolerance;
79  $this->unit = $unit;
80  $this->formula = $formula;
81  $this->setPoints($points);
82  $this->precision = $precision;
83  $this->rating_simple = $rating_simple;
84  $this->rating_sign = $rating_sign;
85  $this->rating_value = $rating_value;
86  $this->rating_unit = $rating_unit;
87  $this->result_type = $result_type;
88  $this->setRangeMinTxt($range_min);
89  $this->setRangeMaxTxt($range_max);
90  }
global $DIC
Definition: feed.php:28
+ 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 118 of file class.assFormulaQuestionResult.php.

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

119  {
120  $resultunits = array();
121  if ($question_id > 0) {
122  $resultunits = $this->getAvailableResultUnits($question_id);
123  }
124 
125  include_once "./Services/Math/classes/class.ilMath.php";
126  include_once "./Services/Math/classes/class.EvalMath.php";
127  $formula = $this->substituteFormula($variables, $results);
128  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
129  foreach ($matches[1] as $variable) {
130  $varObj = $variables[$variable];
131  if (!is_object($varObj)) {
132  continue;
133  }
134  $value = $varObj->getBaseValue();
135  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $value . ")" . "\\1", $formula);
136  }
137  }
138  $math = new EvalMath();
139  $math->suppress_errors = true;
140 
141  $formula = str_replace(",", ".", $formula);
142  $result = $math->evaluate($formula);
143  if (is_object($this->getUnit())) {
144  $result = ilMath::_div($result, $this->getUnit()->getFactor(), 100);
145  }
146 
147  // @todo DON'T USE ilMath::_mul() ... bcmul() returns wrong result !!!!
148 
149  if ($use_precision == true) {
150  $res = $result * 1;
151  if (is_numeric($this->getPrecision())) {
152  if ($this->getResultType() == self::RESULT_DEC || $this->getResultType() == self::RESULT_NO_SELECTION) {
153  $result = ilMath::_round($res, $this->getPrecision());
154  }
155  }
156  }
157  return $result;
158  }
$res
Definition: ltiservices.php:69
static _div($left_operand, $right_operand, int $scale=50)
$results
+ Here is the call graph for this function:

◆ checkSign()

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

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

Referenced by getReachedPoints(), and getResultInfo().

434  : bool
435  {
436  if ((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0))) {
437  return true;
438  } else {
439  return false;
440  }
441  }
+ Here is the caller graph for this function:

◆ convertDecimalToCoprimeFraction()

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

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

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

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

848  {
849  if (empty($decimal_value)) {
850  return '';
851  }
852 
853  $to_string = (string) $decimal_value;
854  $is_negative = strpos($to_string, '-') === 0;
855  if ($is_negative) {
856  $decimal_value = substr($decimal_value, 1);
857  }
858  $h1 = 1;
859  $h2 = 0;
860  $k1 = 0;
861  $k2 = 1;
862  $b = 1 / $decimal_value;
863  do {
864  $b = 1 / $b;
865  $a = floor($b);
866  $aux = $h1;
867  $h1 = $a * $h1 + $h2;
868  $h2 = $aux;
869  $aux = $k1;
870  $k1 = $a * $k1 + $k2;
871  $k2 = $aux;
872  $b = $b - $a;
873  } while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ($k1 < 0 || $b < 0));
874  if ($k1 == 1) {
875  $result = $h1;
876  $checkResult = $h1;
877  } else {
878  $result = "$h1/$k1";
879  $checkResult = ($h1 / $k1);
880  }
881  if ($is_negative) {
882  $result = '-' . $result;
883  $checkResult = ($h1 / $k1) * -1;
884  }
885  if ($to_string == $checkResult . '' || $checkResult . '' == $result) {
886  return $result;
887  } else {
888  return array($to_string,$result);
889  }
890  }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
+ Here is the caller graph for this function:

◆ findValidRandomVariables()

assFormulaQuestionResult::findValidRandomVariables (   $variables,
  $results 
)

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

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

160  : void
161  {
162  include_once "./Services/Math/classes/class.EvalMath.php";
163  $i = 0;
164  $inRange = false;
165  while ($i < 1000 && !$inRange) {
166  $formula = $this->substituteFormula($variables, $results);
167  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
168  foreach ($matches[1] as $variable) {
169  $varObj = $variables[$variable];
170  if (!is_object($varObj)) {
171  continue;
172  }
173  $varObj->setRandomValue();
174  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
175  }
176  }
177  $math = new EvalMath();
178  $math->suppress_errors = true;
179  $result = $math->evaluate($formula);
180  $inRange = (is_numeric($result)) ? true : false;
181  if ($inRange) {
182  if (is_numeric($this->getRangeMin())) {
183  if ($result < $this->getRangeMinBase()) {
184  $inRange = false;
185  }
186  }
187  if (is_numeric($this->getRangeMax())) {
188  if ($result > $this->getRangeMaxBase()) {
189  $inRange = false;
190  }
191  }
192  }
193  $i++;
194  }
195  }
$results
$i
Definition: metadata.php:41
+ Here is the call graph for this function:

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

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

Referenced by calculateFormula().

902  : array
903  {
904  global $DIC;
905  $ilDB = $DIC['ilDB'];
906 
907  $res = $ilDB->queryF(
908  '
909  SELECT * FROM il_qpl_qst_fq_res_unit
910  WHERE question_fi = %s
911  ORDER BY result',
912  array('integer'),
913  array($question_id)
914  );
915 
916 
917  while ($row = $ilDB->fetchAssoc($res)) {
918  $this->available_units[$row['result']][] = $row['unit_fi'] ;
919  }
920 
921  return $this->available_units;
922  }
$res
Definition: ltiservices.php:69
global $DIC
Definition: feed.php:28
+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

References $formula.

Referenced by substituteFormula().

725  : ?string
726  {
727  return $this->formula;
728  }
+ Here is the caller graph for this function:

◆ getGreatestCommonDivisor()

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

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

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

893  {
894  if ($b > 0) {
895  return self::getGreatestCommonDivisor($b, $a % $b);
896  } else {
897  return $a;
898  }
899  }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

References $points.

Referenced by getReachedPoints(), and getResultInfo().

735  : float
736  {
737  return $this->points;
738  }
+ Here is the caller graph for this function:

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

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

References $precision.

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

785  : int
786  {
787  return $this->precision;
788  }
+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

References $range_max.

Referenced by findValidRandomVariables(), and getRangeMaxBase().

+ Here is the caller graph for this function:

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

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

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

Referenced by findValidRandomVariables().

690  {
691  if (is_numeric($this->getRangeMax())) {
692  if (is_object($this->getUnit())) {
693  include_once "./Services/Math/classes/class.ilMath.php";
694  return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
695  }
696  }
697  return $this->getRangeMax();
698  }
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMaxTxt()

assFormulaQuestionResult::getRangeMaxTxt ( )

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

References $range_max_txt.

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

References $range_min.

Referenced by findValidRandomVariables(), and getRangeMinBase().

+ Here is the caller graph for this function:

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

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

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

Referenced by findValidRandomVariables().

658  {
659  if (is_numeric($this->getRangeMin())) {
660  if (is_object($this->getUnit())) {
661  include_once "./Services/Math/classes/class.ilMath.php";
662  return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
663  }
664  }
665  return $this->getRangeMin();
666  }
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMinTxt()

assFormulaQuestionResult::getRangeMinTxt ( )

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

References $range_min_txt.

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

References $rating_sign.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

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

References $rating_simple.

Referenced by getReachedPoints(), and getResultInfo().

745  : bool
746  {
747  return $this->rating_simple;
748  }
+ Here is the caller graph for this function:

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

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

References $rating_unit.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

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

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 443 of file class.assFormulaQuestionResult.php.

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().

444  {
445  global $DIC;
446  $ilLog = $DIC['ilLog'];
447  if ($this->getRatingSimple()) {
448  if ($this->isCorrect($variables, $results, $value, $units[$unit] ?? null)) {
449  return $this->getPoints();
450  } else {
451  return 0;
452  }
453  } else {
454  $points = 0;
455  include_once "./Services/Math/classes/class.EvalMath.php";
456  include_once "./Services/Math/classes/class.ilMath.php";
457  $formula = $this->substituteFormula($variables, $results);
458 
459  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
460  foreach ($matches[1] as $variable) {
461  $varObj = $variables[$variable];
462  if (!is_object($varObj)) {
463  continue;
464  }
465  if ($varObj->getUnit() != null) {
466  //convert unit and value to baseunit
467  if ($varObj->getUnit()->getBaseUnit() != -1) {
468  $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
469  } else {
470  $tmp_value = $varObj->getValue();
471  }
472  } else {
473  $tmp_value = $varObj->getValue();
474  }
475  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
476  }
477  }
478 
479  $math = new EvalMath();
480  $math->suppress_errors = true;
481  $result = $math->evaluate($formula);
482 
483  // result_type extension
484  switch ($this->getResultType()) {
486  if ((substr_count($value, '.') == 1) || (substr_count($value, ',') == 1)) {
487  $exp_val = $value;
488  $frac_value = str_replace(',', '.', $exp_val);
489  } else {
490  $frac_value = $value;
491  }
492  $check_fraction = true;
493  break;
495  $exp_val = explode('/', $value);
496  if (count($exp_val) == 1) {
497  $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
498  if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
499  $check_fraction = true;
500  } else {
501  $check_fraction = false;
502  }
503  } else {
504  $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
505  if (ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision())) {
506  $check_fraction = true;
507  }
508  }
509  break;
511  $exp_val = explode('/', $value);
512  if (count($exp_val) == 1) {
513  $check_fraction = false;
514  } else {
515  $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
516  if (self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
517  $check_fraction = true;
518  }
519  }
520  break;
522  default:
523  $check_fraction = true;
524  break;
525  }
526 
527  // result unit!!
528  if (is_object($this->getUnit())) {
529  // if expected resultunit != baseunit convert to resultunit
530  if ($this->getUnit()->getBaseUnit() != -1) {
531  $result = ilMath::_div($result, $this->getUnit()->getFactor(), $this->getPrecision());
532  } else {
533  //if resultunit == baseunit calculate to get correct precision
534  $result = ilMath::_mul($result, $this->getUnit()->getFactor(), $this->getPrecision());
535  }
536  }
537 
538  if (is_object($unit)) {
539  if (isset($frac_value)) {
540  $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
541  }
542  }
543 
544  if ($this->checkSign($result, $value)) {
545  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
546  }
547 
548  if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
549  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
550  }
551  if (is_object($this->getUnit())) {
552  $base1 = $units[$unit] ?? null;
553  if (is_object($base1)) {
554  $base1 = $units[$base1->getBaseUnit()];
555  }
556  $base2 = $units[$this->getUnit()->getBaseUnit()];
557  if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
558  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
559  }
560  }
561  return $points;
562  }
563  }
static _div($left_operand, $right_operand, int $scale=50)
isInTolerance($user_answer, $expected, $tolerated_percentage)
global $DIC
Definition: feed.php:28
isCorrect($variables, $results, $value, $unit=null)
$results
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

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

References $result.

Referenced by assFormulaQuestion\getResultUnits(), assFormulaQuestionGUI\isSaveCommand(), and substituteFormula().

631  : string
632  {
633  return $this->result;
634  }
+ Here is the caller graph for this function:

◆ getResultInfo()

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

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

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

565  : array
566  {
567  if ($this->getRatingSimple()) {
568  if ($this->isCorrect($variables, $results, $value, $units[$unit] ?? null)) {
569  return array("points" => $this->getPoints());
570  } else {
571  return array("points" => 0);
572  }
573  } else {
574  include_once "./Services/Math/classes/class.EvalMath.php";
575  include_once "./Services/Math/classes/class.ilMath.php";
576  $totalpoints = 0;
577  $formula = $this->substituteFormula($variables, $results);
578  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
579  foreach ($matches[1] as $variable) {
580  $varObj = $variables[$variable];
581  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
582  }
583  }
584  $math = new EvalMath();
585  $math->suppress_errors = true;
586  $result = $math->evaluate($formula);
587  if (is_object($this->getUnit())) {
588  $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
589  }
590  if (is_object($unit)) {
591  $value = ilMath::_mul($value, $unit->getFactor(), 100);
592  } else {
593  }
594  $details = array();
595  if ($this->checkSign($result, $value)) {
596  $points = ilMath::_mul($this->getPoints(), $this->getRatingSign() / 100);
597  $totalpoints += $points;
598  $details['sign'] = $points;
599  }
600  if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
601  $points = ilMath::_mul($this->getPoints(), $this->getRatingValue() / 100);
602  $totalpoints += $points;
603  $details['value'] = $points;
604  }
605  if (is_object($this->getUnit())) {
606  $base1 = $units[$unit];
607  if (is_object($base1)) {
608  $base1 = $units[$base1->getBaseUnit()];
609  }
610  $base2 = $units[$this->getUnit()->getBaseUnit()];
611  if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
612  $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit() / 100);
613  $totalpoints += $points;
614  $details['unit'] = $points;
615  }
616  }
617  $details['points'] = $totalpoints;
618  return $details;
619  }
620  }
isInTolerance($user_answer, $expected, $tolerated_percentage)
array $details
Details for error message relating to last request processed.
Definition: System.php:109
isCorrect($variables, $results, $value, $unit=null)
$results
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:

◆ getResultType()

assFormulaQuestionResult::getResultType ( )

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

References $result_type.

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

795  : int
796  {
797  return (int) $this->result_type;
798  }
+ Here is the caller graph for this function:

◆ getResultTypeByQstId()

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

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

References $DIC, $ilDB, and $res.

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

821  {
822  global $DIC;
823  $ilDB = $DIC['ilDB'];
824 
825  $res = $ilDB->queryF(
826  '
827  SELECT result_type
828  FROM il_qpl_qst_fq_res
829  WHERE question_fi = %s
830  AND result = %s',
831  array('integer', 'text'),
832  array($a_qst_id, $a_result)
833  );
834 
835  $row = $ilDB->fetchAssoc($res);
836 
837  return $row['result_type'];
838  }
$res
Definition: ltiservices.php:69
global $DIC
Definition: feed.php:28
+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

References $tolerance.

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

705  : float
706  {
707  return $this->tolerance;
708  }
+ Here is the caller graph for this function:

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

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

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 840 of file class.assFormulaQuestionResult.php.

840  : bool
841  {
842  $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
843 
844  return $gcd == 1 ? true : false;
845  }

◆ isCorrect()

assFormulaQuestionResult::isCorrect (   $variables,
  $results,
  $value,
  $unit = null 
)
Parameters
$variablesarray formula variables containing units
$resultsarray formula results containing units
$valuestring user input value
null$unituser input unit
Returns
bool

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

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(), getResultInfo(), and assFormulaQuestionTest\testSimpleRatedFormulaQuestionCalculations().

242  : bool
243  {
244  // The user did not answer the question ....
245  if ($value === null || 0 == strlen($value)) {
246  return false;
247  }
248  $value = str_replace(' ', '', $value);
249 
250  include_once "./Services/Math/classes/class.EvalMath.php";
251  include_once "./Services/Math/classes/class.ilMath.php";
252  $formula = $this->substituteFormula($variables, $results);
253 
254  $check_valid_chars = true;
255 
256  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
257  foreach ($matches[1] as $variable) {
258  $varObj = $variables[$variable];
259  if (!is_object($varObj)) {
260  continue;
261  }
262 
263  if ($varObj->getUnit() != null) {
264  //convert unit and value to baseunit.... because vars could have different units
265  if ($varObj->getUnit()->getBaseUnit() != -1) { #$this->getUnit() != NULL)
266  $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
267  } else {
268  $tmp_value = $varObj->getValue();
269  }
270  } else {
271  $tmp_value = $varObj->getValue();
272  }
273 
274  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
275  }
276  }
277 
278  $math = new EvalMath();
279  $math->suppress_errors = true;
280  $result = $math->evaluate($formula); // baseunit-result!!
281  $resultWithRespectedUnit = $result;
282 
283  if (is_object($this->getUnit())) {
284  //there is a "fix" result_unit defined!
285 
286  // if expected resultunit != baseunit convert to "fix" result_unit
287  if ($this->getUnit()->getBaseUnit() != -1) {
288  $resultWithRespectedUnit = ilMath::_div($result, $this->getUnit()->getFactor());
289  }
290  } elseif ($this->getUnit() == null && $unit != null) {
291  // there is no "fix" result_unit defined, but the user has selected a unit ...
292  // so .... there are "available resultunits" in multi-selectbox selected
293  // -> check if selected user-unit is baseunit
294  if ($unit->getFactor() != 1 && strlen(trim($unit->getFactor())) != 1) {
295  // result is already calculated to baseunit.... -> get correct precision..
296  $resultWithRespectedUnit = ilMath::_div($result, $unit->getFactor());
297  }
298  }
299 
300  $result = substr($result, 0, strlen($resultWithRespectedUnit));
301 
302  // check for valid chars ("0-9",",|.|/","0-9","e|E","+|-","0-9")
303  $has_valid_chars = preg_match("/^-?([0-9]*)(,|\\.|\\/){0,1}([0-9]*)([eE][\\+|-]([0-9])+)?$/", $value, $matches);
304  if (!$has_valid_chars) {
305  $check_valid_chars = false;
306  } elseif (
307  (isset($matches[2]) && $matches[2] == '/') &&
308  (isset($matches[4]) && strtolower($matches[4]) == "e") &&
309  (!isset($matches[1]) || !strlen($matches[1]) || !isset($matches[3]) || !strlen($matches[3]) || $matches[3] == 0)) {
310  $check_valid_chars = false;
311  }
312 
313  // result_type extension
314  switch ($this->getResultType()) {
316  if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
317  $exp_val = $value;
318  $frac_value = str_replace(',', '.', $exp_val);
319  } else {
320  $frac_value = $value;
321  }
322 
323  if (substr_count($value, '/') >= 1) {
324  $check_fraction = false;
325  } else {
326  $check_fraction = true;
327  }
328  break;
329 
332  $exp_val = explode('/', $value);
333  if (count($exp_val) == 1) {
334  $frac_value = ilMath::_div($exp_val[0], 1);
335 
336  if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
337  $check_fraction = true;
338  } else {
339  $check_fraction = false;
340  }
341  } else {
342  try {
343  $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
344  } catch (ilMathDivisionByZeroException $ex) {
345  if ($result) {
346  return false;
347  } else {
348  return true;
349  }
350  }
351  $frac_value = str_replace(',', '.', $frac_value);
352 
353  if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
354  $check_fraction = true;
355  }
356 
358  if (!self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
359  $check_fraction = false;
360  }
361  }
362  }
363 
364  if (substr_count($value, '.') >= 1 || substr_count($value, ',') >= 1) {
365  $check_fraction = false;
366  }
367  break;
368 
370  default:
371  if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
372  $frac_value = str_replace(',', '.', $value);
373  } elseif (substr_count($value, '/') == 1) {
374  $exp_val = explode('/', $value);
375  try {
376  $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
377  } catch (ilMathDivisionByZeroException $ex) {
378  if ($result) {
379  return false;
380  } else {
381  return true;
382  }
383  }
384  } else {
385  $frac_value = $value;
386  }
387 
388  $check_fraction = true;
389  break;
390  }
391 
392  if (is_object($unit)) {
393  if (isset($frac_value)) {
394  $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
395  }
396  }
397 
398  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
399  $resultWithRespectedUnit = ilMath::_round($resultWithRespectedUnit, $this->getPrecision());
400 
401  $checkvalue = false;
402  if (isset($frac_value)) {
403  if ($this->isInTolerance($frac_value, $resultWithRespectedUnit, $this->getTolerance())) {
404  $checkvalue = true;
405  }
406  } else {
407  if ($this->isInTolerance($value, $resultWithRespectedUnit, $this->getTolerance())) {
408  $checkvalue = true;
409  }
410  }
411 
412  $checkunit = true;
413  if (is_object($this->getUnit())) {
414  if (is_object($unit)) {
415  if ($unit->getId() != $this->getUnit()->getId()) {
416  $checkunit = false;
417  }
418  }
419  }
420  return $checkvalue && $checkunit && $check_fraction && $check_valid_chars;
421  }
static _div($left_operand, $right_operand, int $scale=50)
isInTolerance($user_answer, $expected, $tolerated_percentage)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$results
static _mul($left_operand, $right_operand, int $scale=50)
+ 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 423 of file class.assFormulaQuestionResult.php.

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

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

423  : bool
424  {
425  $user_answer = ilMath::_mul($user_answer, 1, $this->getPrecision());
426  $tolerance_abs = abs(ilMath::_div(ilMath::_mul($tolerated_percentage, $expected, 100), 100));
427  $lower_boundary = ilMath::_sub($expected, $tolerance_abs);
428  $upper_boundary = ilMath::_add($expected, $tolerance_abs);
429 
430  return $lower_boundary <= $user_answer
431  && $user_answer <= $upper_boundary;
432  }
static _add($left_operand, $right_operand, int $scale=50)
static _div($left_operand, $right_operand, int $scale=50)
static _sub($left_operand, $right_operand, int $scale=50)
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setFormula()

assFormulaQuestionResult::setFormula (   $formula)

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

References $formula.

720  : void
721  {
722  $this->formula = $formula;
723  }

◆ setPoints()

assFormulaQuestionResult::setPoints (   $points)

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

References $points.

Referenced by __construct().

730  : void
731  {
732  $this->points = (float) str_replace(",", ".", $points);
733  }
+ Here is the caller graph for this function:

◆ setPrecision()

assFormulaQuestionResult::setPrecision (   $precision)

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

References $precision.

780  : void
781  {
782  $this->precision = $precision;
783  }

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax (   $range_max)

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

References $range_max, and $result.

Referenced by __construct(), and suggestRange().

668  : void
669  {
670  // include_once "./Services/Math/classes/class.EvalMath.php";
671  // $math = new EvalMath();
672  // $math->suppress_errors = TRUE;
673  // $result = $math->evaluate($range_max);
674  // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
675  // $this->range_max = $val;
676 
677  include_once "./Services/Math/classes/class.EvalMath.php";
678  $math = new EvalMath();
679  $math->suppress_errors = true;
680  $result = $math->evaluate((string) $range_max);
681  $this->range_max = $result;
682  }
+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt (   $range_max_txt)

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

References $range_max_txt.

Referenced by __construct().

800  : void
801  {
802  $this->range_max_txt = $range_max_txt;
803  }
+ Here is the caller graph for this function:

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin (   $range_min)

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

References $range_min, and $result.

Referenced by __construct(), and suggestRange().

636  : void
637  {
638  // include_once "./Services/Math/classes/class.EvalMath.php";
639  // $math = new EvalMath();
640  // $math->suppress_errors = TRUE;
641  // $result = $math->evaluate($range_min);
642  // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
643  // $this->range_min = $val;
644 
645  include_once "./Services/Math/classes/class.EvalMath.php";
646  $math = new EvalMath();
647  $math->suppress_errors = true;
648  $result = $math->evaluate((string) $range_min);
649  $this->range_min = $result;
650  }
+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt (   $range_min_txt)

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

References $range_min_txt.

Referenced by __construct(), and assFormulaQuestionGUI\writePostData().

810  : void
811  {
812  $this->range_min_txt = $range_min_txt;
813  }
+ Here is the caller graph for this function:

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign (   $rating_sign)

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

References $rating_sign.

750  : void
751  {
752  $this->rating_sign = $rating_sign;
753  }

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple (   $rating_simple)

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

References $rating_simple.

740  : void
741  {
742  $this->rating_simple = $rating_simple;
743  }

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit (   $rating_unit)

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

References $rating_unit.

770  : void
771  {
772  $this->rating_unit = $rating_unit;
773  }

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue (   $rating_value)

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

References $rating_value.

760  : void
761  {
762  $this->rating_value = $rating_value;
763  }

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

References $result.

626  : void
627  {
628  $this->result = $result;
629  }

◆ setResultType()

assFormulaQuestionResult::setResultType (   $a_result_type)

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

790  : void
791  {
792  $this->result_type = $a_result_type;
793  }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

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

References $tolerance.

700  : void
701  {
702  $this->tolerance = $tolerance;
703  }

◆ setUnit()

assFormulaQuestionResult::setUnit (   $unit)

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

References $unit.

710  : void
711  {
712  $this->unit = $unit;
713  }

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula (   $variables,
  $results 
)

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

References $DIC, $formula, $lng, $result, $results, getFormula(), and getResult().

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

93  {
94  global $DIC;
95  $lng = $DIC['lng'];
96 
97  $formula = $this->getFormula();
98 
99  if (preg_match_all("/(\\\$r\\d+)/ims", $formula, $matches)) {
100  foreach ($matches[1] as $result) {
101  if (strcmp($result, $this->getResult()) == 0) {
102  $this->main_tpl->setOnScreenMessage('failure', $lng->txt("errRecursionInResult"));
103  return false;
104  }
105 
106  if (is_object($results[$result])) {
107  $formula = str_replace($result, $results[$result]->substituteFormula($variables, $results), $formula);
108  } else {
109  $this->main_tpl->setOnScreenMessage('failure', $lng->txt("errFormulaQuestion"));
110  return false;
111  }
112  }
113  }
114 
115  return "(" . $formula . ")";
116  }
$lng
global $DIC
Definition: feed.php:28
$results
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ suggestRange()

assFormulaQuestionResult::suggestRange (   $variables,
  $results 
)

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

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

197  : void
198  {
199 
200 // @todo Check this
201  include_once "./Services/Math/classes/class.EvalMath.php";
202  $range_min = null;
203  $range_max = null;
204  for ($i = 0; $i < 1000; $i++) {
205  $formula = $this->substituteFormula($variables, $results);
206  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
207  foreach ($matches[1] as $variable) {
208  $varObj = $variables[$variable];
209  if (!is_object($varObj)) {
210  continue;
211  }
212  $varObj->setRandomValue();
213  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
214  }
215  }
216  $math = new EvalMath();
217  $math->suppress_errors = true;
218  $result = $math->evaluate($formula);
219  if (($range_min == null) || ($result < $range_min)) {
221  }
222  if (($range_max == null) || ($result > $range_max)) {
224  }
225  }
226  include_once "./Services/Math/classes/class.ilMath.php";
227  if (is_object($this->getUnit())) {
228  $range_min = ilMath::_div($range_min, $this->getUnit()->getFactor());
229  $range_max = ilMath::_div($range_max, $this->getUnit()->getFactor());
230  }
231  $this->setRangeMin(ilMath::_mul($range_min, 1, $this->getPrecision()));
232  $this->setRangeMax(ilMath::_mul($range_max, 1, $this->getPrecision()));
233  }
static _div($left_operand, $right_operand, int $scale=50)
$results
static _mul($left_operand, $right_operand, int $scale=50)
$i
Definition: metadata.php:41
+ Here is the call graph for this function:

Field Documentation

◆ $available_units

assFormulaQuestionResult::$available_units = array()
private

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

Referenced by getAvailableResultUnits().

◆ $formula

◆ $main_tpl

ilGlobalTemplateInterface assFormulaQuestionResult::$main_tpl
private

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

◆ $points

assFormulaQuestionResult::$points
private

◆ $precision

assFormulaQuestionResult::$precision
private

Definition at line 43 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 46 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 45 of file class.assFormulaQuestionResult.php.

Referenced by getRangeMinTxt(), and setRangeMinTxt().

◆ $rating_sign

assFormulaQuestionResult::$rating_sign
private

Definition at line 39 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 41 of file class.assFormulaQuestionResult.php.

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

◆ $rating_value

assFormulaQuestionResult::$rating_value
private

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

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

◆ $result

◆ $result_type

assFormulaQuestionResult::$result_type
private

Definition at line 44 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: