ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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 public

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

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

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;
70  $this->setRangeMinTxt($range_min);
71  $this->setRangeMaxTxt($range_max);
72  }
+ 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.

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

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)
foreach($_POST as $key=> $value) $res
$results
+ Here is the call graph for this function:

◆ checkSign()

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

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

Referenced by getReachedPoints(), and getResultInfo().

415  {
416  if ((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0))) {
417  return true;
418  } else {
419  return false;
420  }
421  }
+ 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.

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

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

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
+ Here is the caller graph for this function:

◆ findValidRandomVariables()

assFormulaQuestionResult::findValidRandomVariables (   $variables,
  $results 
)

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

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

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  }
$results
$i
Definition: metadata.php:24
+ Here is the call graph for this function:

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

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

Referenced by calculateFormula().

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 
901  return $this->available_units;
902  }
foreach($_POST as $key=> $value) $res
global $DIC
Definition: goto.php:24
global $ilDB
+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

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.

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

873  {
874  if ($b > 0) {
875  return self::getGreatestCommonDivisor($b, $a % $b);
876  } else {
877  return $a;
878  }
879  }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

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.

References $precision.

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

766  {
767  return (int) $this->precision;
768  }
+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

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

Referenced by findValidRandomVariables().

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)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMaxTxt()

assFormulaQuestionResult::getRangeMaxTxt ( )

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

References $range_max_txt.

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

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

Referenced by findValidRandomVariables().

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  }
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMinTxt()

assFormulaQuestionResult::getRangeMinTxt ( )

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

References $range_min_txt.

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

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.

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.

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.

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

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)
static _div($left_operand, $right_operand, $scale=50)
global $DIC
Definition: goto.php:24
isCorrect($variables, $results, $value, $unit=null)
$results
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

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

References $result.

Referenced by assFormulaQuestionGUI\isSaveCommand(), and 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.

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

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  }
isInTolerance($user_answer, $expected, $tolerated_percentage)
isCorrect($variables, $results, $value, $unit=null)
$results
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:

◆ getResultType()

assFormulaQuestionResult::getResultType ( )

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

References $result_type.

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

776  {
777  return (int) $this->result_type;
778  }
+ 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.

References $DIC, $ilDB, and $res.

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

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  }
foreach($_POST as $key=> $value) $res
global $DIC
Definition: goto.php:24
global $ilDB
+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

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.

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  }

◆ 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.

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

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  }
isInTolerance($user_answer, $expected, $tolerated_percentage)
static _div($left_operand, $right_operand, $scale=50)
$results
static _mul($left_operand, $right_operand, $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 403 of file class.assFormulaQuestionResult.php.

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

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

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 _div($left_operand, $right_operand, $scale=50)
static _add($left_operand, $right_operand, $scale=50)
static _mul($left_operand, $right_operand, $scale=50)
static _sub($left_operand, $right_operand, $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 700 of file class.assFormulaQuestionResult.php.

References $formula.

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

◆ setPoints()

assFormulaQuestionResult::setPoints (   $points)

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

References $points.

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

◆ setPrecision()

assFormulaQuestionResult::setPrecision (   $precision)

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

References $precision.

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

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax (   $range_max)

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

References $range_max, and $result.

Referenced by __construct(), and suggestRange().

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  }
+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt (   $range_max_txt)

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

References $range_max_txt.

Referenced by __construct().

781  {
782  $this->range_max_txt = $range_max_txt;
783  }
+ Here is the caller graph for this function:

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin (   $range_min)

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

References $range_min, and $result.

Referenced by __construct(), and suggestRange().

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  }
+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt (   $range_min_txt)

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

References $range_min_txt.

Referenced by __construct().

791  {
792  $this->range_min_txt = $range_min_txt;
793  }
+ Here is the caller graph for this function:

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign (   $rating_sign)

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

References $rating_sign.

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

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple (   $rating_simple)

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

References $rating_simple.

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

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit (   $rating_unit)

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

References $rating_unit.

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

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue (   $rating_value)

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

References $rating_value.

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

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

References $result.

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

◆ 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.

References $tolerance.

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

◆ setUnit()

assFormulaQuestionResult::setUnit (   $unit)

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

References $unit.

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

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula (   $variables,
  $results 
)

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

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

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

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  }
$lng
global $DIC
Definition: goto.php:24
$results
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
+ 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.

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

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  }
static _div($left_operand, $right_operand, $scale=50)
$results
static _mul($left_operand, $right_operand, $scale=50)
$i
Definition: metadata.php:24
+ 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: