Skip to content

Commit

Permalink
ported function convert_value() to the current master. The function h…
Browse files Browse the repository at this point in the history
…as been commited with commits 7a08741, 807dfb8 and f94b98c and has been lost between release 2.0 and 2.05.
  • Loading branch information
weberhofer committed Aug 7, 2014
1 parent b9d0240 commit e0c81bd
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
47 changes: 47 additions & 0 deletions application/helpers/expressions/em_core_helper.php
Expand Up @@ -227,6 +227,7 @@ function __construct()
'sum' => array('array_sum', 'LEMsum', gT('Calculate the sum of values in an array'), 'number sum(arg1, arg2, ... argN)', '', -2),
'sumifop' => array('exprmgr_sumifop', 'LEMsumifop', gT('Sum the values of answered questions in the list which pass the critiera (arg op value)'), 'number sumifop(op, value, arg1, arg2, ... argN)', '', -3),
'tan' => array('tan', 'Math.tan', gT('Tangent'), 'number tan(arg)', 'http://www.php.net/manual/en/function.tan.php', 1),
'convert_value' => array('exprmgr_convert_value', 'LEMconvert_value', gT('Convert a numerical value using a inputTable and outputTable of numerical values'), 'number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)', '', 4),
'time' => array('time', 'time', gT('Return current UNIX timestamp'), 'number time()', 'http://www.php.net/manual/en/function.time.php', 0),
'trim' => array('trim', 'trim', gT('Strip whitespace (or other characters) from the beginning and end of a string'), 'string trim(string [, charlist])', 'http://www.php.net/manual/en/function.trim.php', 1,2),
'ucwords' => array('ucwords', 'ucwords', gT('Uppercase the first character of each word in a string'), 'string ucwords(string)', 'http://www.php.net/manual/en/function.ucwords.php', 1),
Expand Down Expand Up @@ -2576,6 +2577,52 @@ function exprmgr_sumifop($args)
return $result;
}

/**
* Find the closest matching numerical input values in a list an replace it by the
* corresponding value within another list
*
* @author Johannes Weberhofer, 2013
*
* @param numeric $fValueToReplace
* @param numeric $iStrict - 1 for exact matches only otherwise interpolation the
* closest value should be returned
* @param string $sTranslateFromList - comma seperated list of numeric values to translate from
* @param string $sTranslateToList - comma seperated list of numeric values to translate to
* @return numeric
*/
function exprmgr_convert_value($fValueToReplace, $iStrict, $sTranslateFromList, $sTranslateToList)
{
if ( (is_numeric($fValueToReplace)) && ($iStrict!=null) && ($sTranslateFromList!=null) && ($sTranslateToList!=null) )
{
$aFromValues = explode( ',', $sTranslateFromList);
$aToValues = explode( ',', $sTranslateToList);
if ( (count($aFromValues) > 0) && (count($aFromValues) == count($aToValues)) )
{
$fMinimumDiff = null;
$iNearestIndex = 0;
for ( $i = 0; $i < count($aFromValues); $i++) {
if ( !is_numeric($aFromValues[$i])) {
// break processing when non-numeric variables are about to be processed
return null;
}
$fCurrentDiff = abs($aFromValues[$i] - $fValueToReplace);
if ($fCurrentDiff === 0) {
return $aToValues[$i];
} else if ($i === 0) {
$fMinimumDiff = $fCurrentDiff;
} else if ( $fMinimumDiff > $fCurrentDiff ) {
$fMinimumDiff = $fCurrentDiff;
$iNearestIndex = $i;
}
}
if ( $iStrict !== 1 ) {
return $aToValues[$iNearestIndex];
}
}
}
return null;
}

/**
* If $test is true, return $ok, else return $error
* @param <type> $test
Expand Down
14 changes: 13 additions & 1 deletion application/tests/unit/ExpressionManagerTest.php
Expand Up @@ -664,6 +664,18 @@ public function oldTestEvaluator()
NULL~NUMBEROFQUESTIONS-=6
NULL~'Tom'='tired'
NULL~max()
NULL~convert_value( 10, 1, '0,5,10,15,20', '0,5,10,15')
100~convert_value( 10, 1, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( 10, 0, '0,5,10,15,20', '0,50,100,150,200')
100~convert_value( 8, 0, '0,5,10,15,20', '0,50,100,150,200')
100~convert_value( 12, 0, '0,5,10,15,20', '0,50,100,150,200')
0~convert_value( 0, 0, '0,5,10,15,20', '0,50,100,150,200')
0~convert_value( -10000, 0, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( -10000, 1, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 20, 0, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 20, 1, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 30, 0, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( 30, 1, '0,5,10,15,20', '0,50,100,150,200')
EOD;

$atests = explode("\n",$tests);
Expand Down Expand Up @@ -895,4 +907,4 @@ public function oldTokenizer()
}
}

?>
?>
47 changes: 47 additions & 0 deletions scripts/expressions/em_javascript.js
Expand Up @@ -191,6 +191,53 @@ function LEMis_string(a)
return isNaN(a);
}

/**
* Find the closest matching numerical input values in a list an replace it by the
* corresponding value within another list
*
* @author Johannes Weberhofer, 2013
*
* @param numeric fValueToReplace
* @param numeric iStrict - 1 for exact matches only otherwise interpolation the
* closest value should be returned
* @param string sTranslateFromList - comma seperated list of values to translate from
* @param string sTranslateToList - comma seperated list of values to translate to
* @return numeric
*/
function LEMconvert_value( fValueToReplace, iStrict, sTranslateFromList, sTranslateToList)
{
if ( isNaN(fValueToReplace) || (iStrict==null) || (sTranslateFromList==null) || (sTranslateToList==null) )
{
return null;
}
aFromValues = sTranslateFromList.split(",");
aToValues = sTranslateToList.split(",");
if ( (aFromValues.length > 0) && (aFromValues.length == aToValues.length) )
{
fMinimumDiff = null;
iNearestIndex = 0;
for ( i = 0; i < aFromValues.length; i++) {
if ( isNaN(aFromValues[i]) ) {
// break processing when non-numeric variables are about to be processed
return null;
}
fCurrentDiff = Math.abs(aFromValues[i] - fValueToReplace);
if (fCurrentDiff === 0) {
return aToValues[i];
} else if (i === 0) {
fMinimumDiff = fCurrentDiff;
} else if ( fMinimumDiff > fCurrentDiff ) {
fMinimumDiff = fCurrentDiff;
iNearestIndex = i;
}
}
if ( iStrict !== 1 ) {
return aToValues[iNearestIndex];
}
}
return null;
}

function LEMif(a,b,c)
{
// implements conditional logic. Note double negation of a to ensure it is cast to Boolean
Expand Down

0 comments on commit e0c81bd

Please sign in to comment.