ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
assFormulaQuestionResult Class Reference

Formula Question Result. More...

+ Collaboration diagram for assFormulaQuestionResult:

Public Member Functions

 __construct ($result, $range_min, $range_max, $tolerance, $unit, $formula, $points, $precision, $rating_simple=TRUE, $rating_sign=33, $rating_value=34, $rating_unit=33, $result_type=0)
 assFormulaQuestionResult constructor More...
 
 substituteFormula ($variables, $results)
 
 calculateFormula ($variables, $results, $question_id=0, $use_precision=true)
 
 findValidRandomVariables ($variables, $results)
 
 suggestRange ($variables, $results)
 
 isCorrect ($variables, $results, $value, $unit=NULL)
 
 getReachedPoints ($variables, $results, $value, $unit, $units)
 
 getResultInfo ($variables, $results, $value, $unit, $units)
 
 setResult ($result)
 
 getResult ()
 
 setRangeMin ($range_min)
 
 getRangeMin ()
 
 getRangeMinBase ()
 
 setRangeMax ($range_max)
 
 getRangeMax ()
 
 getRangeMaxBase ()
 
 setTolerance ($tolerance)
 
 getTolerance ()
 
 setUnit ($unit)
 
 getUnit ()
 
 setFormula ($formula)
 
 getFormula ()
 
 setPoints ($points)
 
 getPoints ()
 
 setRatingSimple ($rating_simple)
 
 getRatingSimple ()
 
 setRatingSign ($rating_sign)
 
 getRatingSign ()
 
 setRatingValue ($rating_value)
 
 getRatingValue ()
 
 setRatingUnit ($rating_unit)
 
 getRatingUnit ()
 
 setPrecision ($precision)
 
 getPrecision ()
 
 setResultType ($a_result_type)
 
 getResultType ()
 
 setRangeMaxTxt ($range_max_txt)
 
 getRangeMaxTxt ()
 
 setRangeMinTxt ($range_min_txt)
 
 getRangeMinTxt ()
 
 getAvailableResultUnits ($question_id)
 

Static Public Member Functions

static getResultTypeByQstId ($a_qst_id, $a_result)
 
static isCoprimeFraction ($numerator, $denominator)
 
static convertDecimalToCoprimeFraction ($decimal_value, $tolerance=1.e-9)
 
static getGreatestCommonDivisor ($a, $b)
 

Data Fields

const RESULT_NO_SELECTION = 0
 
const RESULT_DEC = 1
 
const RESULT_FRAC = 2
 
const RESULT_CO_FRAC = 3
 

Protected Member Functions

 isInTolerance ($v1, $v2, $p)
 
 checkSign ($v1, $v2)
 

Private Attributes

 $result
 
 $range_min
 
 $range_max
 
 $tolerance
 
 $unit
 
 $formula
 
 $rating_simple
 
 $rating_sign
 
 $rating_value
 
 $rating_unit
 
 $points
 
 $precision
 
 $result_type
 
 $range_min_txt
 
 $range_max_txt
 
 $available_units = array()
 

Detailed Description

Formula Question Result.

Author
Helmut Schottmüller helmu.nosp@m.t.sc.nosp@m.hottm.nosp@m.uell.nosp@m.er@ma.nosp@m.c.co.nosp@m.m
Version
Id
class.assFormulaQuestionResult.php 944 2009-11-09 16:11:30Z hschottm

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

Constructor & Destructor Documentation

◆ __construct()

assFormulaQuestionResult::__construct (   $result,
  $range_min,
  $range_max,
  $tolerance,
  $unit,
  $formula,
  $points,
  $precision,
  $rating_simple = TRUE,
  $rating_sign = 33,
  $rating_value = 34,
  $rating_unit = 33,
  $result_type = 0 
)

assFormulaQuestionResult constructor

Parameters
string$resultResult name
double$range_minRange minimum
double$range_maxRange maximum
double$toleranceTolerance of the result in percent
object$unitUnit
string$formulaThe formula to calculate the result
double$pointsThe maximum available points for the result
integer$precisionNumber of decimal places of the value
boolean$rating_simpleUse simple rating (100% if right, 0 % if wrong)
double$rating_signPercentage of rating for the correct sign
double$rating_valuePercentage of rating for the correct value
double$rating_unitPercentage of rating for the correct unit public

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

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

52  {
53  $this->result = $result;
54  # $this->setRangeMin((is_numeric($range_min)) ? $range_min : NULL);
55  # $this->setRangeMax((is_numeric($range_max)) ? $range_max : NULL);
56  $this->setRangeMin($range_min);
57  $this->setRangeMax($range_max);
58 
59 
60  $this->tolerance = $tolerance;
61  $this->unit = $unit;
62  $this->formula = $formula;
63  $this->points = $points;
64  $this->precision = $precision;
65  $this->rating_simple = $rating_simple;
66  $this->rating_sign = $rating_sign;
67  $this->rating_value = $rating_value;
68  $this->rating_unit = $rating_unit;
69  $this->result_type = $result_type;
70  $this->setRangeMinTxt($range_min);
71  $this->setRangeMaxTxt($range_max);
72  }
+ Here is the call graph for this function:

Member Function Documentation

◆ calculateFormula()

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

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

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

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

◆ checkSign()

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

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

Referenced by getReachedPoints(), and getResultInfo().

479  {
480  if((($v1 >= 0) && ($v2 >= 0)) || (($v1 <= 0) && ($v2 <= 0)))
481  {
482  return TRUE;
483  }
484  else
485  {
486  return FALSE;
487  }
488  }
+ Here is the caller graph for this function:

◆ convertDecimalToCoprimeFraction()

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

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

References $result, $tolerance, array, and string.

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

950  {
951  $to_string = (string) $decimal_value;
952  $is_negative = strpos($to_string, '-') === 0;
953  if($is_negative)
954  {
955  $decimal_value = substr($decimal_value, 1);
956  }
957  $h1=1;
958  $h2=0;
959  $k1=0;
960  $k2=1;
961  $b = 1 / $decimal_value;
962  do {
963  $b = 1 / $b;
964  $a = floor($b);
965  $aux = $h1;
966  $h1 = $a * $h1 + $h2;
967  $h2 = $aux;
968  $aux = $k1;
969  $k1 = $a * $k1 + $k2;
970  $k2 = $aux;
971  $b = $b - $a;
972  }while ((abs($decimal_value - $h1 / $k1) > $decimal_value * $tolerance) || ( $k1 < 0 || $b < 0 ));
973  if($k1 == 1)
974  {
975  $result = $h1;
976  $checkResult = $h1;
977  }
978  else
979  {
980  $result = "$h1/$k1";
981  $checkResult = ($h1/$k1);
982  }
983  if($is_negative)
984  {
985  $result = '-'.$result;
986  $checkResult = ($h1/$k1)*-1;
987  }
988  if($to_string == $checkResult.'' || $checkResult.'' == $result)
989  {
990  return $result;
991  }
992  else
993  {
994  return array($to_string,$result);
995  }
996  }
Add rich text string
The name of the decorator.
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ findValidRandomVariables()

assFormulaQuestionResult::findValidRandomVariables (   $variables,
  $results 
)

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

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

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

◆ getAvailableResultUnits()

assFormulaQuestionResult::getAvailableResultUnits (   $question_id)

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

References $available_units, $ilDB, $res, $row, and array.

Referenced by calculateFormula().

1012  {
1013  global $ilDB;
1014 
1015  $res = $ilDB->queryF('
1016  SELECT * FROM il_qpl_qst_fq_res_unit
1017  WHERE question_fi = %s
1018  ORDER BY result',
1019  array('integer'), array($question_id));
1020 
1021 
1022  while ($row = $ilDB->fetchAssoc($res))
1023  {
1024  $this->available_units[$row['result']][] = $row['unit_fi'] ;
1025  }
1026 
1027  return $this->available_units;
1028  }
Create styles array
The data for the language used.
global $ilDB
+ Here is the caller graph for this function:

◆ getFormula()

assFormulaQuestionResult::getFormula ( )

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

References $formula.

Referenced by substituteFormula().

+ Here is the caller graph for this function:

◆ getGreatestCommonDivisor()

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

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

999  {
1000  if ($b > 0)
1001  {
1002  return self::getGreatestCommonDivisor($b, $a % $b);
1003  }
1004  else
1005  {
1006  return $a;
1007  }
1008  }

◆ getPoints()

assFormulaQuestionResult::getPoints ( )

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

References $points.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getPrecision()

assFormulaQuestionResult::getPrecision ( )

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

References $precision.

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

890  {
891  return (int)$this->precision;
892  }
+ Here is the caller graph for this function:

◆ getRangeMax()

assFormulaQuestionResult::getRangeMax ( )

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

References $range_max.

Referenced by findValidRandomVariables(), and getRangeMaxBase().

+ Here is the caller graph for this function:

◆ getRangeMaxBase()

assFormulaQuestionResult::getRangeMaxBase ( )

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

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

Referenced by findValidRandomVariables().

792  {
793  if(is_numeric($this->getRangeMax()))
794  {
795  if(is_object($this->getUnit()))
796  {
797  include_once "./Services/Math/classes/class.ilMath.php";
798  return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
799  }
800  }
801  return $this->getRangeMax();
802  }
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMaxTxt()

assFormulaQuestionResult::getRangeMaxTxt ( )

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

References $range_max_txt.

◆ getRangeMin()

assFormulaQuestionResult::getRangeMin ( )

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

References $range_min.

Referenced by findValidRandomVariables(), and getRangeMinBase().

+ Here is the caller graph for this function:

◆ getRangeMinBase()

assFormulaQuestionResult::getRangeMinBase ( )

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

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

Referenced by findValidRandomVariables().

757  {
758  if(is_numeric($this->getRangeMin()))
759  {
760  if(is_object($this->getUnit()))
761  {
762  include_once "./Services/Math/classes/class.ilMath.php";
763  return ilMath::_mul($this->getRangeMin(), $this->getUnit()->getFactor(), 100);
764  }
765  }
766  return $this->getRangeMin();
767  }
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRangeMinTxt()

assFormulaQuestionResult::getRangeMinTxt ( )

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

References $range_min_txt.

◆ getRatingSign()

assFormulaQuestionResult::getRatingSign ( )

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

References $rating_sign.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingSimple()

assFormulaQuestionResult::getRatingSimple ( )

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

References $rating_simple.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingUnit()

assFormulaQuestionResult::getRatingUnit ( )

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

References $rating_unit.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getRatingValue()

assFormulaQuestionResult::getRatingValue ( )

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

References $rating_value.

Referenced by getReachedPoints(), and getResultInfo().

+ Here is the caller graph for this function:

◆ getReachedPoints()

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

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

References $formula, $ilLog, $points, $result, $results, $unit, ilMath\_div(), ilMath\_equals(), ilMath\_mul(), checkSign(), getPoints(), getPrecision(), getRatingSign(), getRatingSimple(), getRatingUnit(), getRatingValue(), getResultType(), getTolerance(), getUnit(), isCorrect(), isInTolerance(), RESULT_CO_FRAC, RESULT_DEC, RESULT_FRAC, RESULT_NO_SELECTION, and substituteFormula().

491  {
492  global $ilLog;
493  if($this->getRatingSimple())
494  {
495  if($this->isCorrect($variables, $results, $value, $units[$unit]))
496  {
497  return $this->getPoints();
498  }
499  else
500  {
501  return 0;
502  }
503  }
504  else
505  {
506  $points = 0;
507  include_once "./Services/Math/classes/class.EvalMath.php";
508  include_once "./Services/Math/classes/class.ilMath.php";
509  $formula = $this->substituteFormula($variables, $results);
510 
511  if(preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches))
512  {
513  foreach($matches[1] as $variable)
514  {
515  $varObj = $variables[$variable];
516  if(!is_object($varObj))
517  {
518  continue;
519  }
520  if($varObj->getUnit() != NULL)
521  {
522  //convert unit and value to baseunit
523  if($varObj->getUnit()->getBaseUnit() != -1)
524  {
525  $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
526  }
527  else
528  {
529  $tmp_value = $varObj->getValue();
530  }
531  }
532  else
533  {
534  $tmp_value = $varObj->getValue();
535  }
536  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(".$tmp_value.")" . "\\1", $formula);
537  }
538  }
539 
540  $math = new EvalMath();
541  $math->suppress_errors = TRUE;
542  $result = $math->evaluate($formula);
543 
544 // result_type extension
545  switch($this->getResultType())
546  {
548  if((substr_count($value, '.') == 1) || (substr_count($value, ',') == 1))
549  {
550  $exp_val = $value;
551  $frac_value = str_replace(',', '.', $exp_val);
552  }
553  else
554  {
555  $frac_value = $value;
556  }
557  $check_fraction = TRUE;
558  break;
560  $exp_val = explode('/', $value);
561  if(count($exp_val) == 1)
562  {
563  $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
564  if( ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision()) )
565  {
566  $check_fraction = TRUE;
567  }
568  else
569  {
570  $check_fraction = FALSE;
571  }
572  }
573  else
574  {
575  $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
576  if(ilMath::_equals(abs($frac_value), abs($result), $this->getPrecision()) )
577  {
578  $check_fraction = TRUE;
579  }
580  }
581  break;
583  $exp_val = explode('/', $value);
584  if(count($exp_val) == 1)
585  {
586  $check_fraction = FALSE;
587  }
588  else
589  {
590  $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
591  if(self::isCoprimeFraction($exp_val[0], $exp_val[1]))
592  {
593  $check_fraction = TRUE;
594  }
595  }
596  break;
598  default:
599  $check_fraction = TRUE;
600  break;
601  }
602 
603  // result unit!!
604  if(is_object($this->getUnit()))
605  {
606  // if expected resultunit != baseunit convert to resultunit
607  if($this->getUnit()->getBaseUnit() != -1)
608  {
609  $result = ilMath::_div($result, $this->getUnit()->getFactor(), $this->getPrecision());
610  }
611  else
612  {
613  //if resultunit == baseunit calculate to get correct precision
614  $result = ilMath::_mul($result, $this->getUnit()->getFactor(), $this->getPrecision());
615  }
616  }
617 
618  if(is_object($unit))
619  {
620  if(isset($frac_value))
621  {
622  $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
623  }
624  }
625 
626  if($this->checkSign($result, $value))
627  {
628  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingSign(), 100));
629  }
630  if($this->isInTolerance(abs($value), abs($result), $this->getTolerance()))
631  {
632  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingValue(), 100));
633  }
634  if(is_object($this->getUnit()))
635  {
636  $base1 = $units[$unit];
637  if(is_object($base1)) $base1 = $units[$base1->getBaseUnit()];
638  $base2 = $units[$this->getUnit()->getBaseUnit()];
639  if(is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId())
640  {
641  $points += ilMath::_mul($this->getPoints(), ilMath::_div($this->getRatingUnit(), 100));
642  }
643  }
644  return $points;
645  }
646  }
static _div($left_operand, $right_operand, $scale=50)
static _equals($value1, $value2, $scale)
isCorrect($variables, $results, $value, $unit=NULL)
$results
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:

◆ getResult()

assFormulaQuestionResult::getResult ( )

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

References $result.

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

+ Here is the caller graph for this function:

◆ getResultInfo()

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

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

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

649  {
650  if($this->getRatingSimple())
651  {
652  if($this->isCorrect($variables, $results, $value, $units[$unit]))
653  {
654  return array("points" => $this->getPoints());
655  }
656  else
657  {
658  return array("points" => 0);
659  }
660  }
661  else
662  {
663  include_once "./Services/Math/classes/class.EvalMath.php";
664  include_once "./Services/Math/classes/class.ilMath.php";
665  $totalpoints = 0;
666  $formula = $this->substituteFormula($variables, $results);
667  if(preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches))
668  {
669  foreach($matches[1] as $variable)
670  {
671  $varObj = $variables[$variable];
672  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(".$varObj->getBaseValue().")" . "\\1", $formula);
673  }
674  }
675  $math = new EvalMath();
676  $math->suppress_errors = TRUE;
677  $result = $math->evaluate($formula);
678  if(is_object($this->getUnit()))
679  {
680  $result = ilMath::_mul($result, $this->getUnit()->getFactor(), 100);
681  }
682  if(is_object($unit))
683  {
684  $value = ilMath::_mul($value, $unit->getFactor(), 100);
685  }
686  else
687  {
688  }
689  $details = array();
690  if($this->checkSign($result, $value))
691  {
692  $points = ilMath::_mul($this->getPoints(), $this->getRatingSign()/100);
693  $totalpoints += $points;
694  $details['sign'] = $points;
695  }
696  if($this->isInTolerance(abs($value), abs($result), $this->getTolerance()))
697  {
698  $points = ilMath::_mul($this->getPoints(), $this->getRatingValue()/100);
699  $totalpoints += $points;
700  $details['value'] = $points;
701  }
702  if(is_object($this->getUnit()))
703  {
704  $base1 = $units[$unit];
705  if(is_object($base1)) $base1 = $units[$base1->getBaseUnit()];
706  $base2 = $units[$this->getUnit()->getBaseUnit()];
707  if(is_object($base1) && is_object($base2) && $base1->getId() == $base2->getId())
708  {
709  $points = ilMath::_mul($this->getPoints(), $this->getRatingUnit()/100);
710  $totalpoints += $points;
711  $details['unit'] = $points;
712  }
713  }
714  $details['points'] = $totalpoints;
715  return $details;
716  }
717  }
isCorrect($variables, $results, $value, $unit=NULL)
$results
Create styles array
The data for the language used.
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:

◆ getResultType()

assFormulaQuestionResult::getResultType ( )

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

References $result_type.

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

+ Here is the caller graph for this function:

◆ getResultTypeByQstId()

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

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

References $ilDB, $res, $row, and array.

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

925  {
926  global $ilDB;
927 
928  $res = $ilDB->queryF('
929  SELECT result_type
930  FROM il_qpl_qst_fq_res
931  WHERE question_fi = %s
932  AND result = %s',
933  array('integer', 'text'),
934  array($a_qst_id, $a_result));
935 
936  $row = $ilDB->fetchAssoc($res);
937 
938  return $row['result_type'];
939 
940  }
Create styles array
The data for the language used.
global $ilDB
+ Here is the caller graph for this function:

◆ getTolerance()

assFormulaQuestionResult::getTolerance ( )

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

References $tolerance.

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

+ Here is the caller graph for this function:

◆ getUnit()

assFormulaQuestionResult::getUnit ( )

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

References $unit.

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

+ Here is the caller graph for this function:

◆ isCoprimeFraction()

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

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

943  {
944  $gcd = self::getGreatestCommonDivisor(abs($numerator), abs($denominator));
945 
946  return $gcd == 1 ? true : false;
947  }

◆ isCorrect()

assFormulaQuestionResult::isCorrect (   $variables,
  $results,
  $value,
  $unit = NULL 
)
Parameters
$variablesformula variables containing units
$resultsformula results containing units
$valueuser input value
null$unituser input unit
Returns
bool

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

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

Referenced by getReachedPoints(), getResultInfo(), and assFormulaQuestionTest\testSimpleRatedFormulaQuestionCalculations().

249  {
250  // The user did not answer the question ....
251  if($value === NULL || 0 == strlen($value))
252  {
253  return false;
254  }
255 
256  $value = str_replace(' ', '',$value);
257 
258  include_once "./Services/Math/classes/class.EvalMath.php";
259  include_once "./Services/Math/classes/class.ilMath.php";
260 
261  $formula = $this->substituteFormula($variables, $results);
262 
263  $check_valid_chars = true;
264  if(preg_match_all("/(\\\$v\\d+)/ims", $formula, $matches))
265  {
266  foreach($matches[1] as $variable)
267  {
268  $varObj = $variables[$variable];
269  if(!is_object($varObj))
270  {
271  continue;
272  }
273 
274  if($varObj->getUnit() != NULL)
275  {
276  //convert unit and value to baseunit.... because vars could have different units
277  if($varObj->getUnit()->getBaseUnit() != -1) #$this->getUnit() != NULL)
278  {
279  $tmp_value = $varObj->getValue() * $varObj->getUnit()->getFactor();
280  }
281  else
282  {
283  $tmp_value = $varObj->getValue();
284  }
285  }
286  else
287  {
288  $tmp_value = $varObj->getValue();
289  }
290 
291  $formula = preg_replace("/\\\$" . substr($variable, 1) . "(?![0-9]+)/", "(".$tmp_value.")" . "\\1", $formula);
292  }
293  }
294 
295  $math = new EvalMath();
296  $math->suppress_errors = true;
297  $result = $math->evaluate($formula); // baseunit-result!!
298 
299  $resultWithRespectedUnit = ilMath::_round($result, $this->getPrecision());
300  if(is_object($this->getUnit()))
301  {
302  //there is a "fix" result_unit defined!
303 
304  // if expected resultunit != baseunit convert to "fix" result_unit
305  if($this->getUnit()->getBaseUnit() != -1)
306  {
307  $resultWithRespectedUnit = ilMath::_div($result, $this->getUnit()->getFactor(), $this->getPrecision());
308  }
309  else
310  {
311  //if resultunit == baseunit calculate to get correct precision
312  $resultWithRespectedUnit = ilMath::_mul($result, 1, $this->getPrecision());
313  }
314  }
315  else if($this->getUnit() == NULL && $unit != NULL)
316  {
317  // there is no "fix" result_unit defined, but the user has selected a unit ...
318  // so .... there are "available resultunits" in multi-selectbox selected
319  // -> check if selected user-unit is baseunit
320  if($unit->getFactor() == 1 && strlen(trim($unit->getFactor())) == 1)
321  {
322  // result is already calculated to baseunit.... -> get correct precision..
323  $resultWithRespectedUnit = ilMath::_mul($result, 1, $this->getPrecision());
324  }
325  else
326  {
327  $resultWithRespectedUnit = ilMath::_div($result, $unit->getFactor(), $this->getPrecision());
328  }
329  }
330 
331  // check for valid chars ("0-9",",|.|/","0-9","e|E","+|-","0-9")
332  $has_valid_chars = preg_match("/^-?([0-9]*)(,|\\.|\\/){0,1}([0-9]*)([eE][\\+|-]([0-9])+)?$/", $value, $matches);
333  if(!$has_valid_chars)
334  {
335  $check_valid_chars = false;
336  }
337  else if($matches[2] == '/' && strtolower($matches[4]) == "e" && (!strlen($matches[1]) || !strlen($matches[3]) || $matches[3] == 0))
338  {
339  $check_valid_chars = false;
340  }
341 // result_type extension
342  switch($this->getResultType())
343  {
345  if(substr_count($value, '/') > 0)
346  {
347  $check_fraction = FALSE;
348  }
349  else
350  {
351  $check_fraction = TRUE;
352  }
353 
354  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
355 
356  if(substr_count($value, '.') == 1 || substr_count($value, ',') == 1)
357  {
358  $exp_val = $value;
359  $frac_value = str_replace(',', '.', $exp_val);
360  }
361  else
362  {
363  $frac_value = $value;
364  }
365 
366  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
367  break;
368 
371  $exp_val = explode('/', $value);
372  if(count($exp_val) == 1)
373  {
374  $frac_value = ilMath::_div($exp_val[0], 1, $this->getPrecision());
375  if(ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision()))
376  {
377  $check_fraction = TRUE;
378  }
379  else
380  {
381  $check_fraction = FALSE;
382  }
383  }
384  else
385  {
386  $frac_value = ilMath::_div($exp_val[0], $exp_val[1]);
387  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
388  $frac_value = str_replace(',', '.', $frac_value);
389 
390  if(ilMath::_equals($frac_value, $resultWithRespectedUnit, $this->getPrecision()) )
391  {
392  $check_fraction = TRUE;
393  }
394 
396  {
397  if(!self::isCoprimeFraction($exp_val[0], $exp_val[1]))
398  {
399  $check_fraction = FALSE;
400  }
401  }
402  }
403 
404  if(substr_count($value, '.') > 0 || substr_count($value, ',') > 0)
405  {
406  $check_fraction = FALSE;
407  }
408  break;
409 
411  default:
412  if(substr_count($value, '.') == 1 || substr_count($value, ',') == 1)
413  {
414  $frac_value = str_replace(',', '.', $value);
415  }
416  elseif( substr_count($value, '/') == 1 )
417  {
418  $exp_val = explode('/', $value);
419  $frac_value = ilMath::_div($exp_val[0], $exp_val[1], $this->getPrecision());
420  }
421  else
422  {
423  $frac_value = $value;
424  }
425  $frac_value = ilMath::_round($frac_value, $this->getPrecision());
426  $check_fraction = TRUE;
427  break;
428  }
429 
430  if(is_object($unit))
431  {
432  if(isset($frac_value))
433  {
434  $value = ilMath::_mul($frac_value, $unit->getFactor(), 100);
435  }
436  }
437 
438  $checkvalue = FALSE;
439  if(isset($frac_value))
440  {
441  if($this->isInTolerance($frac_value, $resultWithRespectedUnit, $this->getTolerance()))
442  {
443  $checkvalue = TRUE;
444  }
445  }
446  else
447  {
448  if($this->isInTolerance($value, $resultWithRespectedUnit, $this->getTolerance()))
449  {
450  $checkvalue = TRUE;
451  }
452  }
453 
454  $checkunit = TRUE;
455  if(is_object($this->getUnit()))
456  {
457  if(is_object($unit))
458  {
459  if($unit->getId() != $this->getUnit()->getId())
460  {
461  $checkunit = FALSE;
462  }
463  }
464  }
465  return $checkvalue && $checkunit && $check_fraction && $check_valid_chars;
466  }
static _div($left_operand, $right_operand, $scale=50)
static _equals($value1, $value2, $scale)
static _round($value, $precision=0)
$results
static _mul($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInTolerance()

assFormulaQuestionResult::isInTolerance (   $v1,
  $v2,
  $p 
)
protected

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

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

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

469  {
470  include_once "./Services/Math/classes/class.ilMath.php";
471  $v1 = ilMath::_mul($v1, 1, $this->getPrecision());
472  $b1 = ilMath::_sub($v2, abs(ilMath::_div(ilMath::_mul($p, $v2, 100), 100)), $this->getPrecision());
473  $b2 = ilMath::_add($v2, abs(ilMath::_div(ilMath::_mul($p, $v2, 100), 100)), $this->getPrecision());
474  if(($b1 <= $v1) && ($b2 >= $v1)) return TRUE;
475  else return FALSE;
476  }
static _div($left_operand, $right_operand, $scale=50)
static _add($left_operand, $right_operand, $scale=50)
static _mul($left_operand, $right_operand, $scale=50)
static _sub($left_operand, $right_operand, $scale=50)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setFormula()

assFormulaQuestionResult::setFormula (   $formula)

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

References $formula.

825  {
826  $this->formula = $formula;
827  }

◆ setPoints()

assFormulaQuestionResult::setPoints (   $points)

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

References $points.

835  {
836  $this->points = $points;
837  }

◆ setPrecision()

assFormulaQuestionResult::setPrecision (   $precision)

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

References $precision.

885  {
886  $this->precision = $precision;
887  }

◆ setRangeMax()

assFormulaQuestionResult::setRangeMax (   $range_max)

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

References $range_max, and $result.

Referenced by __construct(), and suggestRange().

770  {
771 // include_once "./Services/Math/classes/class.EvalMath.php";
772 // $math = new EvalMath();
773 // $math->suppress_errors = TRUE;
774 // $result = $math->evaluate($range_max);
775 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
776 // $this->range_max = $val;
777 
778  include_once "./Services/Math/classes/class.EvalMath.php";
779  $math = new EvalMath();
780  $math->suppress_errors = TRUE;
781  $result = $math->evaluate($range_max);
782  $this->range_max = $result;
783 
784  }
+ Here is the caller graph for this function:

◆ setRangeMaxTxt()

assFormulaQuestionResult::setRangeMaxTxt (   $range_max_txt)

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

References $range_max_txt.

Referenced by __construct().

905  {
906  $this->range_max_txt = $range_max_txt;
907  }
+ Here is the caller graph for this function:

◆ setRangeMin()

assFormulaQuestionResult::setRangeMin (   $range_min)

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

References $range_min, and $result.

Referenced by __construct(), and suggestRange().

734  {
735 // include_once "./Services/Math/classes/class.EvalMath.php";
736 // $math = new EvalMath();
737 // $math->suppress_errors = TRUE;
738 // $result = $math->evaluate($range_min);
739 // $val = (strlen($result) > 8) ? strtoupper(sprintf("%e", $result)) : $result;
740 // $this->range_min = $val;
741 
742  include_once "./Services/Math/classes/class.EvalMath.php";
743  $math = new EvalMath();
744  $math->suppress_errors = TRUE;
745  $result = $math->evaluate($range_min);
746  $this->range_min = $result;
747 
748 
749  }
+ Here is the caller graph for this function:

◆ setRangeMinTxt()

assFormulaQuestionResult::setRangeMinTxt (   $range_min_txt)

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

References $range_min_txt.

Referenced by __construct().

915  {
916  $this->range_min_txt = $range_min_txt;
917  }
+ Here is the caller graph for this function:

◆ setRatingSign()

assFormulaQuestionResult::setRatingSign (   $rating_sign)

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

References $rating_sign.

855  {
856  $this->rating_sign = $rating_sign;
857  }

◆ setRatingSimple()

assFormulaQuestionResult::setRatingSimple (   $rating_simple)

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

References $rating_simple.

845  {
846  $this->rating_simple = $rating_simple;
847  }

◆ setRatingUnit()

assFormulaQuestionResult::setRatingUnit (   $rating_unit)

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

References $rating_unit.

875  {
876  $this->rating_unit = $rating_unit;
877  }

◆ setRatingValue()

assFormulaQuestionResult::setRatingValue (   $rating_value)

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

References $rating_value.

865  {
866  $this->rating_value = $rating_value;
867  }

◆ setResult()

assFormulaQuestionResult::setResult (   $result)

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

References $result.

724  {
725  $this->result = $result;
726  }

◆ setResultType()

assFormulaQuestionResult::setResultType (   $a_result_type)

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

895  {
896  $this->result_type = $a_result_type;
897  }

◆ setTolerance()

assFormulaQuestionResult::setTolerance (   $tolerance)

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

References $tolerance.

805  {
806  $this->tolerance = $tolerance;
807  }

◆ setUnit()

assFormulaQuestionResult::setUnit (   $unit)

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

References $unit.

815  {
816  $this->unit = $unit;
817  }

◆ substituteFormula()

assFormulaQuestionResult::substituteFormula (   $variables,
  $results 
)

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

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

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

75  {
76  global $lng;
77 
78  $formula = $this->getFormula();
79 
80  if(preg_match_all("/(\\\$r\\d+)/ims", $formula, $matches))
81  {
82  foreach($matches[1] as $result)
83  {
84  if(strcmp($result, $this->getResult()) == 0)
85  {
86  ilUtil::sendFailure($lng->txt("errRecursionInResult"));
87  return false;
88  }
89 
90  if(is_object($results[$result]))
91  {
92  $formula = str_replace($result, $results[$result]->substituteFormula($variables, $results), $formula);
93  }
94  else
95  {
96  ilUtil::sendFailure($lng->txt("errFormulaQuestion"));
97  return false;
98  }
99  }
100  }
101 
102  return "(".$formula.")";
103  }
$results
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
global $lng
Definition: privfeed.php:17
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ suggestRange()

assFormulaQuestionResult::suggestRange (   $variables,
  $results 
)

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

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

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

Field Documentation

◆ $available_units

assFormulaQuestionResult::$available_units = array()
private

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

Referenced by getAvailableResultUnits().

◆ $formula

◆ $points

assFormulaQuestionResult::$points
private

◆ $precision

assFormulaQuestionResult::$precision
private

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

Referenced by __construct(), getPrecision(), and setPrecision().

◆ $range_max

assFormulaQuestionResult::$range_max
private

◆ $range_max_txt

assFormulaQuestionResult::$range_max_txt
private

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

Referenced by getRangeMaxTxt(), and setRangeMaxTxt().

◆ $range_min

assFormulaQuestionResult::$range_min
private

◆ $range_min_txt

assFormulaQuestionResult::$range_min_txt
private

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

Referenced by getRangeMinTxt(), and setRangeMinTxt().

◆ $rating_sign

assFormulaQuestionResult::$rating_sign
private

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

Referenced by __construct(), getRatingSign(), and setRatingSign().

◆ $rating_simple

assFormulaQuestionResult::$rating_simple
private

◆ $rating_unit

assFormulaQuestionResult::$rating_unit
private

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

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

◆ $rating_value

assFormulaQuestionResult::$rating_value
private

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

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

◆ $result

◆ $result_type

assFormulaQuestionResult::$result_type
private

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

Referenced by __construct(), and getResultType().

◆ $tolerance

assFormulaQuestionResult::$tolerance
private

◆ $unit

assFormulaQuestionResult::$unit
private

◆ RESULT_CO_FRAC

◆ RESULT_DEC

◆ RESULT_FRAC

◆ RESULT_NO_SELECTION

const assFormulaQuestionResult::RESULT_NO_SELECTION = 0

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