ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
assFormulaQuestionResult Class Reference

Formula Question Result. More...

+ Inheritance diagram for assFormulaQuestionResult:
+ 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)
 
 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)
 
 toNormalized (Transformations $transformations, array $context=[])
 Convert the internal state of the implementing object into a language-neutral array structure. More...
 
 fromNormalized (array $normalized, Transformations $transformations)
 Restore the object from its normalized representation. More...
 
 toNormalized (Transformations $transformations, array $context=[])
 Convert the internal state of the implementing object into a language-neutral array structure. More...
 
 fromNormalized (array $normalized, Transformations $transformations)
 Restore the object from its normalized representation. More...
 

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

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

59 {
60 global $DIC;
61 $this->main_tpl = $DIC->ui()->mainTemplate();
62 $this->refinery = $DIC->refinery();
63 $this->lng = $DIC->language();
64 $this->setRangeMin($range_min_txt);
65 $this->setRangeMax($range_max_txt);
66
67 if ($rating_sign === null) {
68 $this->rating_sign = 33;
69 }
70 if ($rating_value === null) {
71 $this->rating_value = 34;
72 }
73 if ($rating_unit === null) {
74 $this->rating_unit = 33;
75 }
76 }
global $DIC
Definition: shib_login.php:26

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

+ Here is the call graph for this function:

Member Function Documentation

◆ calculateCorrectResult()

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

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

456 : float
457 {
458 return round(
459 $this->calculateFormula($variables, $results),
460 $this->precision
461 );
462 }
calculateFormula($variables, $results, $question_id=0, $use_precision=true)
$results

References $results.

◆ calculateFormula()

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

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

105 {
106 $resultunits = [];
107 if ($question_id > 0) {
108 $resultunits = $this->getAvailableResultUnits($question_id);
109 }
110
111 $formula = $this->substituteFormula($variables, $results);
112 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
113 foreach ($matches[1] as $variable) {
114 $varObj = $variables[$variable];
115 if (!is_object($varObj) || !is_numeric($varObj->getValue())) {
116 continue;
117 }
118 $value = $varObj->getBaseValue();
119 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $value . ")" . "\\1", $formula);
120 }
121 }
122 $math = new EvalMath();
123 $math->suppress_errors = true;
124
125 $formula = str_replace(",", ".", $formula);
126 $result = $math->evaluate($formula);
127 if ($this->getUnit() !== null) {
128 $result = ilMath::_div($result, $this->getUnit()->getFactor(), 100);
129 }
130
131 // @todo DON'T USE ilMath::_mul() ... bcmul() returns wrong result !!!!
132
133 if ($use_precision == true) {
134 $res = $result * 1;
135 if (is_numeric($this->getPrecision())) {
136 if ($this->getResultType() == self::RESULT_DEC || $this->getResultType() == self::RESULT_NO_SELECTION) {
137 $result = ilMath::_round($res, $this->getPrecision());
138 }
139 }
140 }
141 return $result;
142 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
substituteFormula(array $variables, array $results)
static _div($left_operand, $right_operand, int $scale=50)
foreach($_POST as $key=> $value) $res

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

+ Here is the call graph for this function:

◆ checkSign()

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

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

412 : bool
413 {
414 return ($v1 >= 0.0 && $v2 >= 0.0) || ($v1 <= 0.0 && $v2 <= 0.0);
415 }

◆ convertDecimalToCoprimeFraction()

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

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

793 {
794 if (empty($decimal_value)) {
795 return '';
796 }
797
798 $to_string = (string) $decimal_value;
799 $is_negative = strpos($to_string, '-') === 0;
800 if ($is_negative) {
801 $decimal_value = substr($decimal_value, 1);
802 }
803 $h1 = 1;
804 $h2 = 0;
805 $k1 = 0;
806 $k2 = 1;
807 $b = 1 / $decimal_value;
808 do {
809 $b = 1 / $b;
810 $a = floor($b);
811 $aux = $h1;
812 $h1 = $a * $h1 + $h2;
813 $h2 = $aux;
814 $aux = $k1;
815 $k1 = $a * $k1 + $k2;
816 $k2 = $aux;
817 $b = $b - $a;
818 } while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ($k1 < 0 || $b < 0));
819 if ($k1 == 1) {
820 $result = $h1;
821 $checkResult = $h1;
822 } else {
823 $result = "$h1/$k1";
824 $checkResult = ($h1 / $k1);
825 }
826 if ($is_negative) {
827 $result = '-' . $result;
828 $checkResult = ($h1 / $k1) * -1;
829 }
830 if ($to_string == $checkResult . '' || $checkResult . '' == $result) {
831 return $result;
832 } else {
833 return [$to_string,$result];
834 }
835 }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

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

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

+ Here is the caller graph for this function:

◆ findValidRandomVariables()

assFormulaQuestionResult::findValidRandomVariables (   $variables,
  $results 
)

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

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

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

+ Here is the call graph for this function:

◆ fromNormalized()

assFormulaQuestionResult::fromNormalized ( array  $normalized,
Transformations  $transformations 
)

Restore the object from its normalized representation.

Parameters
array<array-key,mixed>$normalized

Implements ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\FromNormalized.

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

899 : static
900 {
901 $clone = clone $this;
902 $clone->available_units = array_map(
903 static fn(array $unit): assFormulaQuestionUnit => $transformations->denormalize($unit, new assFormulaQuestionUnit()),
904 $normalized['available_units']
905 );
906 $clone->range_min = $transformations->float($normalized['range_min']);
907 $clone->range_max = $transformations->float($normalized['range_max']);
908 $clone->range_min_txt = $transformations->string($normalized['range_min_txt']);
909 $clone->range_max_txt = $transformations->string($normalized['range_max_txt']);
910 $clone->result = $transformations->string($normalized['result']);
911 $clone->tolerance = $transformations->float($normalized['tolerance']);
912 $clone->unit = $transformations->denormalize($normalized['unit'], new assFormulaQuestionUnit());
913 $clone->formula = $transformations->string($normalized['formula']);
914 $clone->points = $transformations->float($normalized['points']);
915 $clone->precision = $transformations->int($normalized['precision']);
916 $clone->rating_simple = $transformations->bool($normalized['rating_simple']);
917 $clone->rating_sign = $transformations->float($normalized['rating_sign']);
918 $clone->rating_value = $transformations->float($normalized['rating_value']);
919 $clone->rating_unit = $transformations->float($normalized['rating_unit']);
920 $clone->result_type = $transformations->int($normalized['result_type']);
921
922 return $clone;
923 }
denormalize(array|float|bool|int|string|null $normalized, string|object $expected)

References ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\bool(), ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\denormalize(), ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\float(), ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\int(), and ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\string().

+ Here is the call graph for this function:

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

847 : array
848 {
849 global $DIC;
850 $ilDB = $DIC['ilDB'];
851
852 $res = $ilDB->queryF(
853 '
854 SELECT * FROM il_qpl_qst_fq_res_unit
855 WHERE question_fi = %s
856 ORDER BY result',
857 ['integer'],
858 [$question_id]
859 );
860
861
862 while ($row = $ilDB->fetchAssoc($res)) {
863 $this->available_units[$row['result']][] = $row['unit_fi'] ;
864 }
865
867 }

References $DIC, $ilDB, and $res.

Referenced by calculateFormula().

+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

670 : ?string
671 {
672 return $this->formula;
673 }

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

+ Here is the caller graph for this function:

◆ getGreatestCommonDivisor()

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

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

838 {
839 if ($b > 0) {
841 } else {
842 return $a;
843 }
844 }

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

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

680 : float
681 {
682 return $this->points;
683 }

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

+ Here is the caller graph for this function:

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

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

730 : int
731 {
732 return $this->precision;
733 }

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

+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

631 : ?float
632 {
633 return $this->range_max;
634 }

Referenced by findValidRandomVariables().

+ Here is the caller graph for this function:

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

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

637 {
638 if ($this->getUnit() !== null) {
639 return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
640 }
641
642 return $this->getRangeMax();
643 }
static _mul($left_operand, $right_operand, int $scale=50)

References ilMath\_mul().

Referenced by findValidRandomVariables().

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

◆ getRangeMaxTxt()

assFormulaQuestionResult::getRangeMaxTxt ( )

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

750 : string
751 {
752 return $this->range_max_txt;
753 }

Referenced by assFormulaQuestion\buildResultsForLog().

+ Here is the caller graph for this function:

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

606 : ?float
607 {
608 return $this->range_min;
609 }

Referenced by findValidRandomVariables().

+ Here is the caller graph for this function:

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

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

612 {
613 if ($this->getUnit() !== null) {
614 return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
615 }
616
617 return $this->getRangeMin();
618 }

References ilMath\_mul().

Referenced by findValidRandomVariables().

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

◆ getRangeMinTxt()

assFormulaQuestionResult::getRangeMinTxt ( )

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

760 : string
761 {
762 return $this->range_min_txt;
763 }

Referenced by assFormulaQuestion\buildResultsForLog().

+ Here is the caller graph for this function:

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

700 : float
701 {
702 return $this->rating_sign;
703 }

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

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

690 : bool
691 {
692 return $this->rating_simple;
693 }

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

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

720 : float
721 {
722 return $this->rating_unit;
723 }

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

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

710 : float
711 {
712 return $this->rating_value;
713 }

◆ getReachedPoints()

assFormulaQuestionResult::getReachedPoints ( array  $variables,
array  $results,
string  $answer_value,
?assFormulaQuestionUnit  $answer_unit 
)

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

422 : float {
423 if ($this->getRatingSimple()) {
424 return $this->isCorrect($variables, $results, $answer_value, $answer_unit)
425 ? $this->getPoints()
426 : 0.0;
427 }
428
429 $result = $this->calculateCorrectResult($variables, $results);
430 $float_value = $this->transformAnswerValueAccordingToType($answer_value, $answer_unit);
431
432 $points = 0.0;
433 if (
434 $this->unit instanceof assFormulaQuestionUnit
435 && $answer_unit instanceof assFormulaQuestionUnit
436 && $this->unit->getBaseUnit() === $answer_unit->getBaseUnit()
437 ) {
438 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
439 }
440
441 if ($float_value === null) {
442 return $points;
443 }
444
445 if ($this->checkSign($result, $float_value)) {
446 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
447 }
448
449 if ($this->isInTolerance(abs($float_value), abs($result), $this->getTolerance())) {
450 $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
451 }
452
453 return $points;
454 }
isInTolerance($user_answer, $expected, $tolerated_percentage)
calculateCorrectResult(array $variables, array $results)
transformAnswerValueAccordingToType(string $value, ?assFormulaQuestionUnit $unit)
isCorrect($variables, $results, $value, $unit=null)

References $results, getPoints(), and isCorrect().

+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

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

590 : string
591 {
592 return $this->result;
593 }

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

+ Here is the caller graph for this function:

◆ getResultInfo()

assFormulaQuestionResult::getResultInfo (   $variables,
  $results,
  $value,
  $unit,
  $units 
)
Returns
array{sign: int|float, value: int|float, unit: int|float, points: int|float}

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

505 : array
506 {
507 if ($this->getRatingSimple()) {
508 return [
509 'sign' => 0,
510 'value' => 0,
511 'unit' => 0,
512 'points' => $this->isCorrect($variables, $results, $value, $units[$unit] ?? null)
513 ? $this->getPoints()
514 : 0,
515 ];
516 }
517
518 $totalpoints = 0;
519 $formula = $this->substituteFormula($variables, $results);
520 if (preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches)) {
521 foreach ($matches[1] as $variable) {
522 $varObj = $variables[$variable];
523 $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(" . $varObj->getBaseValue() . ")" . "\\1", $formula);
524 }
525 }
526
527 $math = new EvalMath();
528 $math->suppress_errors = true;
529 $result = $math->evaluate($formula);
530
531 if ($this->getUnit() instanceof assFormulaQuestionUnit) {
532 $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
533 }
534
535 if ($unit instanceof assFormulaQuestionUnit) {
536 $value = ilMath::_mul($value, $unit->getFactor(), 100);
537 }
538
539 $details = [
540 'sign' => 0,
541 'value' => 0,
542 'unit' => 0,
543 'points' => 0,
544 ];
545
546 if ($this->checkSign($result, $value)) {
547 $points = ilMath::_mul($this->getPoints(), $this->getRatingSign() / 100);
548 $totalpoints += $points;
549 $details['sign'] = $points;
550 }
551
552 if ($this->isInTolerance(abs($value), abs($result), $this->getTolerance())) {
553 $points = ilMath::_mul($this->getPoints(), $this->getRatingValue() / 100);
554 $totalpoints += $points;
555 $details['value'] = $points;
556 }
557
558 if ($this->getUnit() instanceof assFormulaQuestionUnit) {
559 $base1 = $units[$unit] ?? null;
560 if ($base1 instanceof assFormulaQuestionUnit) {
561 $base1 = $units[$base1->getBaseUnit()];
562 }
563
564 $base2 = $units[$this->getUnit()->getBaseUnit()];
565 if (
566 $base1 instanceof assFormulaQuestionUnit
567 && $base2 instanceof assFormulaQuestionUnit
568 && $base1->getId() === $base2->getId()
569 ) {
570 $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit() / 100);
571 $totalpoints += $points;
572 $details['unit'] = $points;
573 }
574 }
575
576 $details['points'] = $totalpoints;
577
578 return $details;
579 }

References $results, ilMath\_mul(), and assFormulaQuestionUnit\getId().

+ Here is the call graph for this function:

◆ getResultType()

assFormulaQuestionResult::getResultType ( )

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

740 : int
741 {
742 return (int) $this->result_type;
743 }

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

+ Here is the caller graph for this function:

◆ getResultTypeByQstId()

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

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

766 {
767 global $DIC;
768 $ilDB = $DIC['ilDB'];
769
770 $res = $ilDB->queryF(
771 '
772 SELECT result_type
773 FROM il_qpl_qst_fq_res
774 WHERE question_fi = %s
775 AND result = %s',
776 ['integer', 'text'],
777 [$a_qst_id, $a_result]
778 );
779
780 $row = $ilDB->fetchAssoc($res);
781
782 return $row['result_type'];
783 }

References $DIC, $ilDB, and $res.

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

+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

650 : float
651 {
652 return $this->tolerance;
653 }

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

+ Here is the caller graph for this function:

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

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

661 {
662 return $this->unit;
663 }

Referenced by assFormulaQuestion\buildResultsForLog(), calculateFormula(), assFormulaQuestion\canUseAdvancedRating(), isCorrect(), assFormulaQuestion\loadFromDb(), and suggestRange().

+ Here is the caller graph for this function:

◆ isCoprimeFraction()

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

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

785 : bool
786 {
787 $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
788
789 return $gcd == 1 ? true : false;
790 }

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

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

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

Referenced by getReachedPoints().

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

401 : bool
402 {
403 $user_answer = ilMath::_mul($user_answer, 1, $this->getPrecision());
404 $tolerance_abs = abs(ilMath::_div(ilMath::_mul($tolerated_percentage, $expected, 100), 100));
405 $lower_boundary = ilMath::_sub($expected, $tolerance_abs);
406 $upper_boundary = ilMath::_add($expected, $tolerance_abs);
407
408 return $lower_boundary <= $user_answer
409 && $user_answer <= $upper_boundary;
410 }
static _sub($left_operand, $right_operand, int $scale=50)
static _add($left_operand, $right_operand, int $scale=50)

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

Referenced by isCorrect().

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

◆ setFormula()

assFormulaQuestionResult::setFormula ( ?string  $formula)

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

665 : void
666 {
667 $this->formula = $formula;
668 }

◆ setPoints()

assFormulaQuestionResult::setPoints ( float  $points)

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

675 : void
676 {
677 $this->points = $points;
678 }

◆ setPrecision()

assFormulaQuestionResult::setPrecision ( float  $precision)

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

725 : void
726 {
727 $this->precision = $precision;
728 }

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax ( ?string  $range_max)

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

620 : void
621 {
622 if ($range_max === null) {
623 return;
624 }
625
626 $math = new EvalMath();
627 $math->suppress_errors = true;
628 $this->range_max = (float) $math->evaluate($range_max);
629 }

Referenced by __construct(), and suggestRange().

+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt ( string  $range_max_txt)

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

745 : void
746 {
747 $this->range_max_txt = $range_max_txt;
748 }

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin ( ?string  $range_min)

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

595 : void
596 {
597 if ($range_min === null) {
598 return;
599 }
600
601 $math = new EvalMath();
602 $math->suppress_errors = true;
603 $this->range_min = (float) $math->evaluate($range_min);
604 }

Referenced by __construct(), and suggestRange().

+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt ( string  $range_min_txt)

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

755 : void
756 {
757 $this->range_min_txt = $range_min_txt;
758 }

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign ( float  $rating_sign)

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

695 : void
696 {
697 $this->rating_sign = $rating_sign;
698 }

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple ( bool  $rating_simple)

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

685 : void
686 {
687 $this->rating_simple = $rating_simple;
688 }

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit ( float  $rating_unit)

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

715 : void
716 {
717 $this->rating_unit = $rating_unit;
718 }

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue ( float  $rating_value)

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

705 : void
706 {
707 $this->rating_value = $rating_value;
708 }

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

585 : void
586 {
587 $this->result = $result;
588 }

◆ setResultType()

assFormulaQuestionResult::setResultType ( int  $a_result_type)

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

735 : void
736 {
737 $this->result_type = $a_result_type;
738 }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

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

645 : void
646 {
647 $this->tolerance = $tolerance;
648 }

◆ setUnit()

assFormulaQuestionResult::setUnit ( ?assFormulaQuestionUnit  $unit)

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

655 : void
656 {
657 $this->unit = $unit;
658 }

◆ substituteFormula()

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

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

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

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

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

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

◆ suggestRange()

assFormulaQuestionResult::suggestRange (   $variables,
  $results 
)

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

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

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

+ Here is the call graph for this function:

◆ toNormalized()

assFormulaQuestionResult::toNormalized ( Transformations  $transformations,
array  $context = [] 
)

Convert the internal state of the implementing object into a language-neutral array structure.

The resulting array must contain only null, scalar values (string, int, float, bool) and nested arrays following the same rules.

Parameters
array<string,mixed>$context
Returns
array<array-key, mixed>|float|bool|int|string|null

Implements ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\ToNormalized.

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

873 : array|float|bool|int|string|null
874 {
875 return [
876 'available_units' => $transformations->normalize($this->available_units),
877 'range_min' => $this->range_min,
878 'range_max' => $this->range_max,
879 'range_min_txt' => $this->range_min_txt,
880 'range_max_txt' => $this->range_max_txt,
881 'result' => $this->result,
882 'tolerance' => $this->tolerance,
883 'unit' => $transformations->normalize($this->unit),
884 'formula' => $this->formula,
885 'points' => $this->points,
886 'precision' => $this->precision,
887 'rating_simple' => $this->rating_simple,
888 'rating_sign' => $this->rating_sign,
889 'rating_value' => $this->rating_value,
890 'rating_unit' => $this->rating_unit,
891 'result_type' => $this->result_type,
892 ];
893 }

References ILIAS\TestQuestionPool\ExportImport\Foundation\Normalize\Transformations\normalize().

+ Here is the call graph for this function:

◆ transformAnswerValueAccordingToType()

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

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

467 : ?float {
468 switch ($this->getResultType()) {
469 case self::RESULT_DEC:
470 break;
473 $exp_val = explode('/', $value);
474 $value = ilMath::_div(
475 $exp_val[0],
476 count($exp_val) === 1 ? 1 : $exp_val[1],
477 $this->getPrecision()
478 );
479 break;
481 default:
482 $exp_val = explode('/', $value);
483
484 if (count($exp_val) === 2
485 && (float) $exp_val[1] === 0.0) {
486 return null;
487 }
488
489 $value = ilMath::_div(
490 $exp_val[0],
491 count($exp_val) === 1 ? 1 : $exp_val[1],
492 100
493 );
494 }
495
496 return $this->refinery->byTrying([
497 $this->refinery->kindlyTo()->float(),
498 $this->refinery->always(null),
499 ])->transform(round($value, $this->precision));
500 }

References ilMath\_div().

+ Here is the call graph for this function:

Field Documentation

◆ $available_units

assFormulaQuestionResult::$available_units = []
private

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

◆ $lng

ilLanguage assFormulaQuestionResult::$lng
private

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

◆ $main_tpl

ilGlobalTemplateInterface assFormulaQuestionResult::$main_tpl
private

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

◆ $range_max

float assFormulaQuestionResult::$range_max = null
private

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

Referenced by suggestRange().

◆ $range_min

float assFormulaQuestionResult::$range_min = null
private

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

Referenced by suggestRange().

◆ $refinery

Refinery assFormulaQuestionResult::$refinery
private

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