ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
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 (private string $result, private ?string $range_min_txt, private ?string $range_max_txt, private float $tolerance, private ?assFormulaQuestionUnit $unit, private ?string $formula, private float $points, private int $precision, private bool $rating_simple=true, private ?float $rating_sign=null, private ?float $rating_value=null, private ?float $rating_unit=null, private float $result_type=0)
 
 substituteFormula (array $variables, array $results)
 
 calculateFormula ($variables, $results, $question_id=0, $use_precision=true)
 
 findValidRandomVariables ($variables, $results)
 
 suggestRange ($variables, $results)
 
 isCorrect ($variables, $results, $value, $unit=null)
 
 getReachedPoints (array $variables, array $results, string $answer_value, ?assFormulaQuestionUnit $answer_unit, array $units)
 
 getResultInfo ($variables, $results, $value, $unit, $units)
 
 setResult ($result)
 
 getResult ()
 
 setRangeMin (?string $range_min)
 
 getRangeMin ()
 
 getRangeMinBase ()
 
 setRangeMax (?string $range_max)
 
 getRangeMax ()
 
 getRangeMaxBase ()
 
 setTolerance ($tolerance)
 
 getTolerance ()
 
 setUnit (?assFormulaQuestionUnit $unit)
 
 getUnit ()
 
 setFormula (?string $formula)
 
 getFormula ()
 
 setPoints (float $points)
 
 getPoints ()
 
 setRatingSimple (bool $rating_simple)
 
 getRatingSimple ()
 
 setRatingSign (float $rating_sign)
 
 getRatingSign ()
 
 setRatingValue (float $rating_value)
 
 getRatingValue ()
 
 setRatingUnit (float $rating_unit)
 
 getRatingUnit ()
 
 setPrecision (float $precision)
 
 getPrecision ()
 
 setResultType (int $a_result_type)
 
 getResultType ()
 
 setRangeMaxTxt (string $range_max_txt)
 
 getRangeMaxTxt ()
 
 setRangeMinTxt (string $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)
 

Private Member Functions

 checkSign (float $v1, float $v2)
 
 calculateCorrectResult (array $variables, array $results)
 
 transformAnswerValueAccordingToType (string $value, ?assFormulaQuestionUnit $unit)
 

Private Attributes

ilGlobalTemplateInterface $main_tpl
 
Refinery $refinery
 
ilLanguage $lng
 
 $available_units = []
 
float $range_min = null
 
float $range_max = null
 

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

Constructor & Destructor Documentation

◆ __construct()

assFormulaQuestionResult::__construct ( private string  $result,
private ?string  $range_min_txt,
private ?string  $range_max_txt,
private float  $tolerance,
private ?assFormulaQuestionUnit  $unit,
private ?string  $formula,
private float  $points,
private int  $precision,
private bool  $rating_simple = true,
private ?float  $rating_sign = null,
private ?float  $rating_value = null,
private ?float  $rating_unit = null,
private float  $result_type = 0 
)

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

References $DIC, ILIAS\Repository\lng(), null, ILIAS\Repository\refinery(), setRangeMax(), and setRangeMin().

56  {
57  global $DIC;
58  $this->main_tpl = $DIC->ui()->mainTemplate();
59  $this->refinery = $DIC->refinery();
60  $this->lng = $DIC->language();
61  $this->setRangeMin($range_min_txt);
62  $this->setRangeMax($range_max_txt);
63 
64  if ($rating_sign === null) {
65  $this->rating_sign = 33;
66  }
67  if ($rating_value === null) {
68  $this->rating_value = 34;
69  }
70  if ($rating_unit === null) {
71  $this->rating_unit = 33;
72  }
73  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:26
+ Here is the call graph for this function:

Member Function Documentation

◆ calculateCorrectResult()

assFormulaQuestionResult::calculateCorrectResult ( array  $variables,
array  $results 
)
private

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

References calculateFormula().

Referenced by getReachedPoints().

461  : float
462  {
463  return round(
464  $this->calculateFormula($variables, $results),
465  $this->precision
466  );
467  }
calculateFormula($variables, $results, $question_id=0, $use_precision=true)
$results
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculateFormula()

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

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

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

Referenced by calculateCorrectResult().

102  {
103  $resultunits = [];
104  if ($question_id > 0) {
105  $resultunits = $this->getAvailableResultUnits($question_id);
106  }
107 
108  $formula = $this->substituteFormula($variables, $results);
109  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
110  foreach ($matches[1] as $variable) {
111  $varObj = $variables[$variable];
112  if (!is_object($varObj) || !is_numeric($varObj->getValue())) {
113  continue;
114  }
115  $value = $varObj->getBaseValue();
116  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $value . ")" . "\\1", $formula);
117  }
118  }
119  $math = new EvalMath();
120  $math->suppress_errors = true;
121 
122  $formula = str_replace(",", ".", $formula);
123  $result = $math->evaluate($formula);
124  if ($this->getUnit() !== null) {
125  $result = ilMath::_div($result, $this->getUnit()->getFactor(), 100);
126  }
127 
128  // @todo DON'T USE ilMath::_mul() ... bcmul() returns wrong result !!!!
129 
130  if ($use_precision == true) {
131  $res = $result * 1;
132  if (is_numeric($this->getPrecision())) {
133  if ($this->getResultType() == self::RESULT_DEC || $this->getResultType() == self::RESULT_NO_SELECTION) {
134  $result = ilMath::_round($res, $this->getPrecision());
135  }
136  }
137  }
138  return $result;
139  }
$res
Definition: ltiservices.php:66
substituteFormula(array $variables, array $results)
static _div($left_operand, $right_operand, int $scale=50)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$results
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkSign()

assFormulaQuestionResult::checkSign ( float  $v1,
float  $v2 
)
private

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

Referenced by getReachedPoints(), and getResultInfo().

409  : bool
410  {
411  return ($v1 >= 0.0 && $v2 >= 0.0) || ($v1 <= 0.0 && $v2 <= 0.0);
412  }
+ Here is the caller graph for this function:

◆ convertDecimalToCoprimeFraction()

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

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

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

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

774  {
775  if (empty($decimal_value)) {
776  return '';
777  }
778 
779  $to_string = (string) $decimal_value;
780  $is_negative = strpos($to_string, '-') === 0;
781  if ($is_negative) {
782  $decimal_value = substr($decimal_value, 1);
783  }
784  $h1 = 1;
785  $h2 = 0;
786  $k1 = 0;
787  $k2 = 1;
788  $b = 1 / $decimal_value;
789  do {
790  $b = 1 / $b;
791  $a = floor($b);
792  $aux = $h1;
793  $h1 = $a * $h1 + $h2;
794  $h2 = $aux;
795  $aux = $k1;
796  $k1 = $a * $k1 + $k2;
797  $k2 = $aux;
798  $b = $b - $a;
799  } while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ($k1 < 0 || $b < 0));
800  if ($k1 == 1) {
801  $result = $h1;
802  $checkResult = $h1;
803  } else {
804  $result = "$h1/$k1";
805  $checkResult = ($h1 / $k1);
806  }
807  if ($is_negative) {
808  $result = '-' . $result;
809  $checkResult = ($h1 / $k1) * -1;
810  }
811  if ($to_string == $checkResult . '' || $checkResult . '' == $result) {
812  return $result;
813  } else {
814  return [$to_string,$result];
815  }
816  }
$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 141 of file class.assFormulaQuestionResult.php.

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

141  : void
142  {
143  $i = 0;
144  $inRange = false;
145  while ($i < 1000 && !$inRange) {
146  $formula = $this->substituteFormula($variables, $results);
147  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
148  foreach ($matches[1] as $variable) {
149  $varObj = $variables[$variable];
150  if (!is_object($varObj)) {
151  continue;
152  }
153  $varObj->setRandomValue();
154  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
155  }
156  }
157  $math = new EvalMath();
158  $math->suppress_errors = true;
159  $result = $math->evaluate($formula);
160  $inRange = (is_numeric($result)) ? true : false;
161  if ($inRange) {
162  if (is_numeric($this->getRangeMin())) {
163  if ($result < $this->getRangeMinBase()) {
164  $inRange = false;
165  }
166  }
167  if (is_numeric($this->getRangeMax())) {
168  if ($result > $this->getRangeMaxBase()) {
169  $inRange = false;
170  }
171  }
172  }
173  $i++;
174  }
175  }
substituteFormula(array $variables, array $results)
$results
+ Here is the call graph for this function:

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

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

Referenced by calculateFormula().

828  : array
829  {
830  global $DIC;
831  $ilDB = $DIC['ilDB'];
832 
833  $res = $ilDB->queryF(
834  '
835  SELECT * FROM il_qpl_qst_fq_res_unit
836  WHERE question_fi = %s
837  ORDER BY result',
838  ['integer'],
839  [$question_id]
840  );
841 
842 
843  while ($row = $ilDB->fetchAssoc($res)) {
844  $this->available_units[$row['result']][] = $row['unit_fi'] ;
845  }
846 
847  return $this->available_units;
848  }
$res
Definition: ltiservices.php:66
global $DIC
Definition: shib_login.php:26
+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

Referenced by assFormulaQuestion\buildResultsForLog(), and substituteFormula().

651  : ?string
652  {
653  return $this->formula;
654  }
+ Here is the caller graph for this function:

◆ getGreatestCommonDivisor()

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

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

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

819  {
820  if ($b > 0) {
821  return self::getGreatestCommonDivisor($b, $a % $b);
822  } else {
823  return $a;
824  }
825  }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

Referenced by assFormulaQuestion\buildResultsForLog(), getReachedPoints(), and getResultInfo().

661  : float
662  {
663  return $this->points;
664  }
+ Here is the caller graph for this function:

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

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

Referenced by assFormulaQuestion\buildResultsForLog(), calculateFormula(), isCorrect(), isInTolerance(), suggestRange(), and transformAnswerValueAccordingToType().

711  : int
712  {
713  return $this->precision;
714  }
+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

References $range_max.

Referenced by findValidRandomVariables(), and getRangeMaxBase().

612  : ?float
613  {
614  return $this->range_max;
615  }
+ Here is the caller graph for this function:

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

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

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

Referenced by findValidRandomVariables().

618  {
619  if ($this->getUnit() !== null) {
620  return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
621  }
622 
623  return $this->getRangeMax();
624  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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 731 of file class.assFormulaQuestionResult.php.

Referenced by assFormulaQuestion\buildResultsForLog().

731  : string
732  {
733  return $this->range_max_txt;
734  }
+ Here is the caller graph for this function:

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

References $range_min.

Referenced by findValidRandomVariables(), and getRangeMinBase().

587  : ?float
588  {
589  return $this->range_min;
590  }
+ Here is the caller graph for this function:

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

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

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

Referenced by findValidRandomVariables().

593  {
594  if ($this->getUnit() !== null) {
595  return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
596  }
597 
598  return $this->getRangeMin();
599  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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 741 of file class.assFormulaQuestionResult.php.

Referenced by assFormulaQuestion\buildResultsForLog().

741  : string
742  {
743  return $this->range_min_txt;
744  }
+ Here is the caller graph for this function:

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

Referenced by getReachedPoints(), and getResultInfo().

681  : float
682  {
683  return $this->rating_sign;
684  }
+ Here is the caller graph for this function:

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

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

Referenced by getReachedPoints(), and getResultInfo().

671  : bool
672  {
673  return $this->rating_simple;
674  }
+ Here is the caller graph for this function:

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

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

Referenced by getReachedPoints(), and getResultInfo().

701  : float
702  {
703  return $this->rating_unit;
704  }
+ Here is the caller graph for this function:

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

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

Referenced by getReachedPoints(), and getResultInfo().

691  : float
692  {
693  return $this->rating_value;
694  }
+ Here is the caller graph for this function:

◆ getReachedPoints()

assFormulaQuestionResult::getReachedPoints ( array  $variables,
array  $results,
string  $answer_value,
?assFormulaQuestionUnit  $answer_unit,
array  $units 
)
Parameters
assFormulaQuestionUnit[]$units

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

References ilMath\_div(), ilMath\_mul(), calculateCorrectResult(), checkSign(), assFormulaQuestionUnit\getBaseUnit(), getPoints(), getRatingSign(), getRatingSimple(), getRatingUnit(), getRatingValue(), getTolerance(), isCorrect(), isInTolerance(), null, and transformAnswerValueAccordingToType().

423  : float {
424  if ($this->getRatingSimple()) {
425  return $this->isCorrect($variables, $results, $answer_value, $answer_unit)
426  ? $this->getPoints()
427  : 0.0;
428  }
429 
430  $result = $this->calculateCorrectResult($variables, $results);
431  $float_value = $this->transformAnswerValueAccordingToType($answer_value, $answer_unit);
432 
433  $points = 0.0;
434  if ($answer_unit instanceof assFormulaQuestionUnit && $answer_unit instanceof assFormulaQuestionUnit) {
435  $base1 = $units[$answer_unit->getBaseUnit()] ?? null;
436  $base2 = $units[$answer_unit->getBaseUnit()] ?? null;
437  if (
438  $base1 instanceof assFormulaQuestionUnit
439  && $base2 instanceof assFormulaQuestionUnit
440  && $base1->getId() === $base2->getId()
441  ) {
442  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
443  }
444  }
445 
446  if ($float_value === null) {
447  return $points;
448  }
449 
450  if ($this->checkSign($result, $float_value)) {
451  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
452  }
453 
454  if ($this->isInTolerance(abs($float_value), abs($result), $this->getTolerance())) {
455  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
456  }
457 
458  return $points;
459  }
static _div($left_operand, $right_operand, int $scale=50)
isInTolerance($user_answer, $expected, $tolerated_percentage)
transformAnswerValueAccordingToType(string $value, ?assFormulaQuestionUnit $unit)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
isCorrect($variables, $results, $value, $unit=null)
$results
calculateCorrectResult(array $variables, array $results)
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

◆ getResultInfo()

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

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

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

507  : array
508  {
509  if ($this->getRatingSimple()) {
510  if ($this->isCorrect($variables, $results, $value, $units[$unit] ?? null)) {
511  return ["points" => $this->getPoints()];
512  } else {
513  return ["points" => 0];
514  }
515  } else {
516  $totalpoints = 0;
517  $formula = $this->substituteFormula($variables, $results);
518  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
519  foreach ($matches[1] as $variable) {
520  $varObj = $variables[$variable];
521  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
522  }
523  }
524  $math = new EvalMath();
525  $math->suppress_errors = true;
526  $result = $math->evaluate($formula);
527  if ($this->getUnit() !== null) {
528  $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
529  }
530  if (is_object($unit)) {
531  $value = ilMath::_mul($value, $unit->getFactor(), 100);
532  } else {
533  }
534  $details = [];
535  if ($this->checkSign($result, $value)) {
536  $points = ilMath::_mul($this->getPoints(), $this->getRatingSign() / 100);
537  $totalpoints += $points;
538  $details['sign'] = $points;
539  }
540  if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
541  $points = ilMath::_mul($this->getPoints(), $this->getRatingValue() / 100);
542  $totalpoints += $points;
543  $details['value'] = $points;
544  }
545  if ($this->getUnit() !== null) {
546  $base1 = $units[$unit];
547  if (is_object($base1)) {
548  $base1 = $units[$base1->getBaseUnit()];
549  }
550  $base2 = $units[$this->getUnit()->getBaseUnit()];
551  if (is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId()) {
552  $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit() / 100);
553  $totalpoints += $points;
554  $details['unit'] = $points;
555  }
556  }
557  $details['points'] = $totalpoints;
558  return $details;
559  }
560  }
substituteFormula(array $variables, array $results)
isInTolerance($user_answer, $expected, $tolerated_percentage)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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 721 of file class.assFormulaQuestionResult.php.

Referenced by assFormulaQuestion\buildResultsForLog(), calculateFormula(), isCorrect(), and transformAnswerValueAccordingToType().

721  : int
722  {
723  return (int) $this->result_type;
724  }
+ Here is the caller graph for this function:

◆ getResultTypeByQstId()

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

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

References $DIC, $ilDB, and $res.

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

747  {
748  global $DIC;
749  $ilDB = $DIC['ilDB'];
750 
751  $res = $ilDB->queryF(
752  '
753  SELECT result_type
754  FROM il_qpl_qst_fq_res
755  WHERE question_fi = %s
756  AND result = %s',
757  ['integer', 'text'],
758  [$a_qst_id, $a_result]
759  );
760 
761  $row = $ilDB->fetchAssoc($res);
762 
763  return $row['result_type'];
764  }
$res
Definition: ltiservices.php:66
global $DIC
Definition: shib_login.php:26
+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

Referenced by assFormulaQuestion\buildResultsForLog(), getReachedPoints(), getResultInfo(), and isCorrect().

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

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

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

Referenced by assFormulaQuestion\buildResultsForLog(), calculateFormula(), getRangeMaxBase(), getRangeMinBase(), getResultInfo(), isCorrect(), and suggestRange().

642  {
643  return $this->unit;
644  }
+ Here is the caller graph for this function:

◆ isCoprimeFraction()

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

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

766  : bool
767  {
768  $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
769 
770  return $gcd == 1 ? true : false;
771  }

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

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

Referenced by getReachedPoints(), and getResultInfo().

219  : bool
220  {
221  // The user did not answer the question ....
222  if ($value === null || 0 == strlen($value)) {
223  return false;
224  }
225  $value = str_replace(' ', '', $value);
226 
227  $formula = $this->substituteFormula($variables, $results);
228 
229  $check_valid_chars = true;
230 
231  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
232  foreach ($matches[1] as $variable) {
233  $varObj = $variables[$variable];
234  if (!is_object($varObj) || !is_numeric($varObj->getValue())) {
235  continue;
236  }
237 
238  if ($varObj->getUnit() != null) {
239  //convert unit and value to baseunit.... because vars could have different units
240  if ($varObj->getUnit()->getBaseUnit() != -1) {
241  $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
242  } else {
243  $tmp_value = $varObj->getValue();
244  }
245  } else {
246  $tmp_value = $varObj->getValue();
247  }
248 
249  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $tmp_value . ")" . "\\1", $formula);
250  }
251  }
252 
253  $math = new EvalMath();
254  $math->suppress_errors = true;
255  $result = $math->evaluate($formula); // baseunit-result!!
256  $resultWithRespectedUnit = $result;
257 
258  if ($this->getUnit() !== null) {
259  //there is a "fix" result_unit defined!
260 
261  // if expected resultunit != baseunit convert to "fix" result_unit
262  if ($this->getUnit()->getBaseUnit() != -1) {
263  $resultWithRespectedUnit = ilMath::_div($result, $this->getUnit()->getFactor());
264  }
265  } elseif ($this->getUnit() == null && $unit != null) {
266  // there is no "fix" result_unit defined, but the user has selected a unit ...
267  // so .... there are "available resultunits" in multi-selectbox selected
268  // -> check if selected user-unit is baseunit
269  if ($unit->getFactor() != 1 && strlen(trim($unit->getFactor())) != 1) {
270  // result is already calculated to baseunit.... -> get correct precision..
271  $resultWithRespectedUnit = ilMath::_div($result, $unit->getFactor());
272  }
273  }
274 
275  $result = substr($result, 0, strlen($resultWithRespectedUnit));
276 
277  // check for valid chars ("0-9",",|.|/","0-9","e|E","+|-","0-9")
278  $has_valid_chars = preg_match("/^-?([0-9]*)(,|\\.|\\/){0,1}([0-9]*)([eE][\\+|-]([0-9])+)?$/", $value, $matches);
279  if (!$has_valid_chars) {
280  $check_valid_chars = false;
281  } elseif (
282  (isset($matches[2]) && $matches[2] == '/') &&
283  (isset($matches[4]) && strtolower($matches[4]) == "e") &&
284  (!isset($matches[1]) || !strlen($matches[1]) || !isset($matches[3]) || !strlen($matches[3]) || $matches[3] == 0)) {
285  $check_valid_chars = false;
286  }
287 
288  // result_type extension
289  switch ($this->getResultType()) {
291  if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
292  $exp_val = $value;
293  $frac_value = str_replace(',', '.', $exp_val);
294  } else {
295  $frac_value = $value;
296  }
297 
298  if (substr_count($value, '/') >= 1) {
299  $check_fraction = false;
300  } else {
301  $check_fraction = true;
302  }
303  break;
304 
307  $exp_val = explode('/', $value);
308  if (count($exp_val) == 1) {
309  $frac_value = ilMath::_div($exp_val[0], 1);
310 
311  if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
312  $check_fraction = true;
313  } else {
314  $check_fraction = false;
315  }
316  } else {
317  try {
318  $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
319  } catch (ilMathDivisionByZeroException $ex) {
320  if ($result) {
321  return false;
322  } else {
323  return true;
324  }
325  }
326  $frac_value = str_replace(',', '.', $frac_value);
327 
328  if (ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision())) {
329  $check_fraction = true;
330  }
331 
333  if (!self::isCoprimeFraction($exp_val[0], $exp_val[1])) {
334  $check_fraction = false;
335  }
336  }
337  }
338 
339  if (substr_count($value, '.') >= 1 || substr_count($value, ',') >= 1) {
340  $check_fraction = false;
341  }
342  break;
343 
345  default:
346  if (substr_count($value, '.') == 1 || substr_count($value, ',') == 1) {
347  $frac_value = str_replace(',', '.', $value);
348  } elseif (substr_count($value, '/') == 1) {
349  $exp_val = explode('/', $value);
350  try {
351  $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
352  } catch (ilMathDivisionByZeroException $ex) {
353  if ($result) {
354  return false;
355  } else {
356  return true;
357  }
358  }
359  } else {
360  $frac_value = $value;
361  }
362 
363  $check_fraction = true;
364  break;
365  }
366 
367  if (is_object($unit)) {
368  if (isset($frac_value)) {
369  $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
370  }
371  }
372 
373  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
374  $resultWithRespectedUnit = ilMath::_round($resultWithRespectedUnit, $this->getPrecision());
375 
376  $checkvalue = false;
377  if (isset($frac_value)) {
378  if ($this->isInTolerance($frac_value, $resultWithRespectedUnit, $this->getTolerance())) {
379  $checkvalue = true;
380  }
381  } else {
382  if ($this->isInTolerance($value, $resultWithRespectedUnit, $this->getTolerance())) {
383  $checkvalue = true;
384  }
385  }
386 
387  $checkunit = true;
388  if ($this->getUnit() !== null) {
389  if (is_object($unit)) {
390  if ($unit->getId() != $this->getUnit()->getId()) {
391  $checkunit = false;
392  }
393  }
394  }
395  return $checkvalue && $checkunit && $check_fraction && $check_valid_chars;
396  }
substituteFormula(array $variables, array $results)
static _div($left_operand, $right_operand, int $scale=50)
isInTolerance($user_answer, $expected, $tolerated_percentage)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$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 398 of file class.assFormulaQuestionResult.php.

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

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

398  : bool
399  {
400  $user_answer = ilMath::_mul($user_answer, 1, $this->getPrecision());
401  $tolerance_abs = abs(ilMath::_div(ilMath::_mul($tolerated_percentage, $expected, 100), 100));
402  $lower_boundary = ilMath::_sub($expected, $tolerance_abs);
403  $upper_boundary = ilMath::_add($expected, $tolerance_abs);
404 
405  return $lower_boundary <= $user_answer
406  && $user_answer <= $upper_boundary;
407  }
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 ( ?string  $formula)

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

646  : void
647  {
648  $this->formula = $formula;
649  }

◆ setPoints()

assFormulaQuestionResult::setPoints ( float  $points)

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

656  : void
657  {
658  $this->points = $points;
659  }

◆ setPrecision()

assFormulaQuestionResult::setPrecision ( float  $precision)

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

706  : void
707  {
708  $this->precision = $precision;
709  }

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax ( ?string  $range_max)

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

References null.

Referenced by __construct(), and suggestRange().

601  : void
602  {
603  if ($range_max === null) {
604  return;
605  }
606 
607  $math = new EvalMath();
608  $math->suppress_errors = true;
609  $this->range_max = (float) $math->evaluate($range_max);
610  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt ( string  $range_max_txt)

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

726  : void
727  {
728  $this->range_max_txt = $range_max_txt;
729  }

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin ( ?string  $range_min)

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

References null.

Referenced by __construct(), and suggestRange().

576  : void
577  {
578  if ($range_min === null) {
579  return;
580  }
581 
582  $math = new EvalMath();
583  $math->suppress_errors = true;
584  $this->range_min = (float) $math->evaluate($range_min);
585  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt ( string  $range_min_txt)

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

736  : void
737  {
738  $this->range_min_txt = $range_min_txt;
739  }

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign ( float  $rating_sign)

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

676  : void
677  {
678  $this->rating_sign = $rating_sign;
679  }

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple ( bool  $rating_simple)

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

666  : void
667  {
668  $this->rating_simple = $rating_simple;
669  }

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit ( float  $rating_unit)

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

696  : void
697  {
698  $this->rating_unit = $rating_unit;
699  }

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue ( float  $rating_value)

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

686  : void
687  {
688  $this->rating_value = $rating_value;
689  }

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

566  : void
567  {
568  $this->result = $result;
569  }

◆ setResultType()

assFormulaQuestionResult::setResultType ( int  $a_result_type)

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

716  : void
717  {
718  $this->result_type = $a_result_type;
719  }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

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

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

◆ setUnit()

assFormulaQuestionResult::setUnit ( ?assFormulaQuestionUnit  $unit)

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

636  : void
637  {
638  $this->unit = $unit;
639  }

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula ( array  $variables,
array  $results 
)

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

References getFormula(), getResult(), and ILIAS\Repository\lng().

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

75  : false|string
76  {
77  $formula = $this->getFormula();
78  preg_match_all('/\$r\d+/mi', $formula, $matches);
79 
80  foreach ($matches[0] as $result) {
81  if ($result === $this->getResult()) {
82  $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('errRecursionInResult'));
83  return false;
84  }
85 
86  if (!isset($results[$result]) || !$results[$result] instanceof self) {
87  $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('errFormulaQuestion'));
88  return false;
89  }
90 
91  $formula = preg_replace(
92  '/\\' . $result . '(?!\d)/m',
93  $results[$result]->substituteFormula($variables, $results),
94  $formula,
95  );
96  }
97 
98  return "({$formula})";
99  }
substituteFormula(array $variables, array $results)
$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 177 of file class.assFormulaQuestionResult.php.

References $results, ilMath\_div(), ilMath\_mul(), getPrecision(), getUnit(), null, setRangeMax(), setRangeMin(), and substituteFormula().

177  : void
178  {
179  // @todo Check this
180  $range_min = null;
181  $range_max = null;
182  for ($i = 0; $i < 1000; $i++) {
183  $formula = $this->substituteFormula($variables, $results);
184  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
185  foreach ($matches[1] as $variable) {
186  $varObj = $variables[$variable];
187  if (!is_object($varObj)) {
188  continue;
189  }
190  $varObj->setRandomValue();
191  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
192  }
193  }
194  $math = new EvalMath();
195  $math->suppress_errors = true;
196  $result = $math->evaluate($formula);
197  if (($range_min == null) || ($result < $range_min)) {
198  $range_min = $result;
199  }
200  if (($range_max == null) || ($result > $range_max)) {
201  $range_max = $result;
202  }
203  }
204  if ($this->getUnit() !== null) {
205  $range_min = ilMath::_div($range_min, $this->getUnit()->getFactor());
206  $range_max = ilMath::_div($range_max, $this->getUnit()->getFactor());
207  }
208  $this->setRangeMin(ilMath::_mul($range_min, 1, $this->getPrecision()));
209  $this->setRangeMax(ilMath::_mul($range_max, 1, $this->getPrecision()));
210  }
substituteFormula(array $variables, array $results)
static _div($left_operand, $right_operand, int $scale=50)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$results
static _mul($left_operand, $right_operand, int $scale=50)
+ Here is the call graph for this function:

◆ transformAnswerValueAccordingToType()

assFormulaQuestionResult::transformAnswerValueAccordingToType ( string  $value,
?assFormulaQuestionUnit  $unit 
)
private

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

References ilMath\_div(), getPrecision(), getResultType(), null, ILIAS\Repository\refinery(), and ILIAS\Refinery\transform().

Referenced by getReachedPoints().

472  : ?float {
473  switch ($this->getResultType()) {
474  case self::RESULT_DEC:
475  break;
476  case self::RESULT_FRAC:
477  case self::RESULT_CO_FRAC:
478  $exp_val = explode('/', $value);
479  $value = ilMath::_div(
480  $exp_val[0],
481  count($exp_val) === 1 ? 1 : $exp_val[1],
482  $this->getPrecision()
483  );
484  break;
485  case self::RESULT_NO_SELECTION:
486  default:
487  $exp_val = explode('/', $value);
488 
489  if (count($exp_val) === 2
490  && (float) $exp_val[1] === 0.0) {
491  return null;
492  }
493 
494  $value = ilMath::_div(
495  $exp_val[0],
496  count($exp_val) === 1 ? 1 : $exp_val[1],
497  100
498  );
499  }
500 
501  return $this->refinery->byTrying([
502  $this->refinery->kindlyTo()->float(),
503  $this->refinery->always(null),
504  ])->transform(round($value, $this->precision));
505  }
static _div($left_operand, $right_operand, int $scale=50)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $available_units

assFormulaQuestionResult::$available_units = []
private

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

Referenced by getAvailableResultUnits().

◆ $lng

ilLanguage assFormulaQuestionResult::$lng
private

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

◆ $main_tpl

ilGlobalTemplateInterface assFormulaQuestionResult::$main_tpl
private

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

◆ $range_max

float assFormulaQuestionResult::$range_max = null
private

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

Referenced by getRangeMax().

◆ $range_min

float assFormulaQuestionResult::$range_min = null
private

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

Referenced by getRangeMin().

◆ $refinery

Refinery assFormulaQuestionResult::$refinery
private

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

◆ RESULT_CO_FRAC

◆ RESULT_DEC

const assFormulaQuestionResult::RESULT_DEC = 1

◆ RESULT_FRAC

◆ RESULT_NO_SELECTION

const assFormulaQuestionResult::RESULT_NO_SELECTION = 0

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