ILIAS  trunk Revision v11.0_alpha-1744-gb0451eebef4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator 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 (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 ($variables, $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
 
 $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 41 of file class.assFormulaQuestionResult.php.

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

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

Member Function Documentation

◆ calculateCorrectResult()

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

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

References calculateFormula().

Referenced by getReachedPoints().

459  : float
460  {
461  return round(
462  $this->calculateFormula($variables, $results),
463  $this->precision
464  );
465  }
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 99 of file class.assFormulaQuestionResult.php.

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

Referenced by calculateCorrectResult().

100  {
101  $resultunits = [];
102  if ($question_id > 0) {
103  $resultunits = $this->getAvailableResultUnits($question_id);
104  }
105 
106  $formula = $this->substituteFormula($variables, $results);
107  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
108  foreach ($matches[1] as $variable) {
109  $varObj = $variables[$variable];
110  if (!is_object($varObj) || !is_numeric($varObj->getValue())) {
111  continue;
112  }
113  $value = $varObj->getBaseValue();
114  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $value . ")" . "\\1", $formula);
115  }
116  }
117  $math = new EvalMath();
118  $math->suppress_errors = true;
119 
120  $formula = str_replace(",", ".", $formula);
121  $result = $math->evaluate($formula);
122  if ($this->getUnit() !== null) {
123  $result = ilMath::_div($result, $this->getUnit()->getFactor(), 100);
124  }
125 
126  // @todo DON'T USE ilMath::_mul() ... bcmul() returns wrong result !!!!
127 
128  if ($use_precision == true) {
129  $res = $result * 1;
130  if (is_numeric($this->getPrecision())) {
131  if ($this->getResultType() == self::RESULT_DEC || $this->getResultType() == self::RESULT_NO_SELECTION) {
132  $result = ilMath::_round($res, $this->getPrecision());
133  }
134  }
135  }
136  return $result;
137  }
$res
Definition: ltiservices.php:66
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 407 of file class.assFormulaQuestionResult.php.

Referenced by getReachedPoints(), and getResultInfo().

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

◆ convertDecimalToCoprimeFraction()

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

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

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

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

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

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

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

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

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

Referenced by calculateFormula().

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

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

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

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

◆ getGreatestCommonDivisor()

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

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

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

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

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

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

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

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

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

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

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

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

References $range_max.

Referenced by findValidRandomVariables(), and getRangeMaxBase().

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

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

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

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

Referenced by findValidRandomVariables().

616  {
617  if ($this->getUnit() !== null) {
618  return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
619  }
620 
621  return $this->getRangeMax();
622  }
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 729 of file class.assFormulaQuestionResult.php.

Referenced by assFormulaQuestion\buildResultsForLog().

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

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

References $range_min.

Referenced by findValidRandomVariables(), and getRangeMinBase().

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

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

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

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

Referenced by findValidRandomVariables().

591  {
592  if ($this->getUnit() !== null) {
593  return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
594  }
595 
596  return $this->getRangeMin();
597  }
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 739 of file class.assFormulaQuestionResult.php.

Referenced by assFormulaQuestion\buildResultsForLog().

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

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

Referenced by getReachedPoints(), and getResultInfo().

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

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

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

Referenced by getReachedPoints(), and getResultInfo().

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

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

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

Referenced by getReachedPoints(), and getResultInfo().

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

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

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

Referenced by getReachedPoints(), and getResultInfo().

689  : float
690  {
691  return $this->rating_value;
692  }
+ 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 415 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().

421  : float {
422  if ($this->getRatingSimple()) {
423  return $this->isCorrect($variables, $results, $answer_value, $answer_unit)
424  ? $this->getPoints()
425  : 0.0;
426  }
427 
428  $result = $this->calculateCorrectResult($variables, $results);
429  $float_value = $this->transformAnswerValueAccordingToType($answer_value, $answer_unit);
430 
431  $points = 0.0;
432  if ($answer_unit instanceof assFormulaQuestionUnit && $answer_unit instanceof assFormulaQuestionUnit) {
433  $base1 = $units[$answer_unit->getBaseUnit()] ?? null;
434  $base2 = $units[$answer_unit->getBaseUnit()] ?? null;
435  if (
436  $base1 instanceof assFormulaQuestionUnit
437  && $base2 instanceof assFormulaQuestionUnit
438  && $base1->getId() === $base2->getId()
439  ) {
440  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
441  }
442  }
443 
444  if ($float_value === null) {
445  return $points;
446  }
447 
448  if ($this->checkSign($result, $float_value)) {
449  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
450  }
451 
452  if ($this->isInTolerance(abs($float_value), abs($result), $this->getTolerance())) {
453  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
454  }
455 
456  return $points;
457  }
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 505 of file class.assFormulaQuestionResult.php.

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

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

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

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

◆ getResultTypeByQstId()

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

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

References $DIC, $ilDB, and $res.

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

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

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

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

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

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

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

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

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

◆ isCoprimeFraction()

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

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

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

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

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

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

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

396  : bool
397  {
398  $user_answer = ilMath::_mul($user_answer, 1, $this->getPrecision());
399  $tolerance_abs = abs(ilMath::_div(ilMath::_mul($tolerated_percentage, $expected, 100), 100));
400  $lower_boundary = ilMath::_sub($expected, $tolerance_abs);
401  $upper_boundary = ilMath::_add($expected, $tolerance_abs);
402 
403  return $lower_boundary <= $user_answer
404  && $user_answer <= $upper_boundary;
405  }
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 644 of file class.assFormulaQuestionResult.php.

644  : void
645  {
646  $this->formula = $formula;
647  }

◆ setPoints()

assFormulaQuestionResult::setPoints ( float  $points)

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

654  : void
655  {
656  $this->points = $points;
657  }

◆ setPrecision()

assFormulaQuestionResult::setPrecision ( float  $precision)

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

704  : void
705  {
706  $this->precision = $precision;
707  }

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax ( ?string  $range_max)

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

References null.

Referenced by __construct(), and suggestRange().

599  : void
600  {
601  if ($range_max === null) {
602  return;
603  }
604 
605  $math = new EvalMath();
606  $math->suppress_errors = true;
607  $this->range_max = (float) $math->evaluate($range_max);
608  }
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 724 of file class.assFormulaQuestionResult.php.

724  : void
725  {
726  $this->range_max_txt = $range_max_txt;
727  }

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin ( ?string  $range_min)

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

References null.

Referenced by __construct(), and suggestRange().

574  : void
575  {
576  if ($range_min === null) {
577  return;
578  }
579 
580  $math = new EvalMath();
581  $math->suppress_errors = true;
582  $this->range_min = (float) $math->evaluate($range_min);
583  }
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 734 of file class.assFormulaQuestionResult.php.

734  : void
735  {
736  $this->range_min_txt = $range_min_txt;
737  }

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign ( float  $rating_sign)

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

674  : void
675  {
676  $this->rating_sign = $rating_sign;
677  }

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple ( bool  $rating_simple)

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

664  : void
665  {
666  $this->rating_simple = $rating_simple;
667  }

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit ( float  $rating_unit)

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

694  : void
695  {
696  $this->rating_unit = $rating_unit;
697  }

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue ( float  $rating_value)

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

684  : void
685  {
686  $this->rating_value = $rating_value;
687  }

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

564  : void
565  {
566  $this->result = $result;
567  }

◆ setResultType()

assFormulaQuestionResult::setResultType ( int  $a_result_type)

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

714  : void
715  {
716  $this->result_type = $a_result_type;
717  }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

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

624  : void
625  {
626  $this->tolerance = $tolerance;
627  }

◆ setUnit()

assFormulaQuestionResult::setUnit ( ?assFormulaQuestionUnit  $unit)

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

634  : void
635  {
636  $this->unit = $unit;
637  }

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula (   $variables,
  $results 
)

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

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

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

74  {
75  global $DIC;
76  $lng = $DIC['lng'];
77 
78  $formula = $this->getFormula();
79 
80  if (preg_match_all("/(\\\$r\\d+)/ims", $formula, $matches)) {
81  foreach ($matches[1] as $result) {
82  if (strcmp($result, $this->getResult()) == 0) {
83  $this->main_tpl->setOnScreenMessage('failure', $lng->txt("errRecursionInResult"));
84  return false;
85  }
86 
87  if (is_object($results[$result])) {
88  $formula = str_replace($result, $results[$result]->substituteFormula($variables, $results), $formula);
89  } else {
90  $this->main_tpl->setOnScreenMessage('failure', $lng->txt("errFormulaQuestion"));
91  return false;
92  }
93  }
94  }
95 
96  return "(" . $formula . ")";
97  }
global $DIC
Definition: shib_login.php:22
$results
global $lng
Definition: privfeed.php:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ suggestRange()

assFormulaQuestionResult::suggestRange (   $variables,
  $results 
)

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

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

175  : void
176  {
177  // @todo Check this
178  $range_min = null;
179  $range_max = null;
180  for ($i = 0; $i < 1000; $i++) {
181  $formula = $this->substituteFormula($variables, $results);
182  if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
183  foreach ($matches[1] as $variable) {
184  $varObj = $variables[$variable];
185  if (!is_object($varObj)) {
186  continue;
187  }
188  $varObj->setRandomValue();
189  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
190  }
191  }
192  $math = new EvalMath();
193  $math->suppress_errors = true;
194  $result = $math->evaluate($formula);
195  if (($range_min == null) || ($result < $range_min)) {
196  $range_min = $result;
197  }
198  if (($range_max == null) || ($result > $range_max)) {
199  $range_max = $result;
200  }
201  }
202  if ($this->getUnit() !== null) {
203  $range_min = ilMath::_div($range_min, $this->getUnit()->getFactor());
204  $range_max = ilMath::_div($range_max, $this->getUnit()->getFactor());
205  }
206  $this->setRangeMin(ilMath::_mul($range_min, 1, $this->getPrecision()));
207  $this->setRangeMax(ilMath::_mul($range_max, 1, $this->getPrecision()));
208  }
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 467 of file class.assFormulaQuestionResult.php.

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

Referenced by getReachedPoints().

470  : ?float {
471  switch ($this->getResultType()) {
472  case self::RESULT_DEC:
473  break;
474  case self::RESULT_FRAC:
475  case self::RESULT_CO_FRAC:
476  $exp_val = explode('/', $value);
477  $value = ilMath::_div(
478  $exp_val[0],
479  count($exp_val) === 1 ? 1 : $exp_val[1],
480  $this->getPrecision()
481  );
482  break;
483  case self::RESULT_NO_SELECTION:
484  default:
485  $exp_val = explode('/', $value);
486 
487  if (count($exp_val) === 2
488  && (float) $exp_val[1] === 0.0) {
489  return null;
490  }
491 
492  $value = ilMath::_div(
493  $exp_val[0],
494  count($exp_val) === 1 ? 1 : $exp_val[1],
495  100
496  );
497  }
498 
499  return $this->refinery->byTrying([
500  $this->refinery->kindlyTo()->float(),
501  $this->refinery->always(null),
502  ])->transform(round($value, $this->precision));
503  }
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 37 of file class.assFormulaQuestionResult.php.

Referenced by getAvailableResultUnits().

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

Referenced by getRangeMax().

◆ $range_min

float assFormulaQuestionResult::$range_min = null
private

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