From 2874b1134189634853c3afaaf46c045f66d51ab9 Mon Sep 17 00:00:00 2001 From: Fatih Kızmaz Date: Mon, 16 May 2022 18:12:36 +0300 Subject: Small support for arrays => min, max and avg funcs accept array argument. (handwritten arrays not supported yet, can be used for array variables or functions returning an array) (#107) invalid expression -> "max([1,2,3])" valid expression -> "max($ages_arr)" valid expression -> "max(ages_arr())" --- src/NXP/MathExecutor.php | 34 +++++++++++++++++++++++++++++----- tests/MathTest.php | 26 +++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php index b3e539b..e7e8259 100644 --- a/src/NXP/MathExecutor.php +++ b/src/NXP/MathExecutor.php @@ -16,6 +16,7 @@ use NXP\Classes\Operator; use NXP\Classes\Token; use NXP\Classes\Tokenizer; use NXP\Exception\DivisionByZeroException; +use NXP\Exception\IncorrectNumberOfFunctionParametersException; use NXP\Exception\MathExecutorException; use NXP\Exception\UnknownVariableException; use ReflectionException; @@ -390,7 +391,18 @@ class MathExecutor 'atan2' => static fn($arg1, $arg2) => \atan2($arg1, $arg2), 'atanh' => static fn($arg) => \atanh($arg), 'atn' => static fn($arg) => \atan($arg), - 'avg' => static fn($arg1, $arg2) => ($arg1 + $arg2) / 2, + 'avg' => static function($arg1, $args) { + if (\is_array($arg1)){ + return \array_sum($arg1) / \count($arg1); + } + + if (0 === \count($args)){ + throw new IncorrectNumberOfFunctionParametersException(); + } + $args = [$arg1, ...$args]; + + return \array_sum($args) / \count($args); + }, 'bindec' => static fn($arg) => \bindec($arg), 'ceil' => static fn($arg) => \ceil($arg), 'cos' => static fn($arg) => \cos($arg), @@ -431,8 +443,20 @@ class MathExecutor 'log' => static fn($arg) => \log($arg), 'log10' => static fn($arg) => \log10($arg), 'log1p' => static fn($arg) => \log1p($arg), - 'max' => static fn($arg1, $arg2, ...$args) => \max($arg1, $arg2, ...$args), - 'min' => static fn($arg1, $arg2, ...$args) => \min($arg1, $arg2, ...$args), + 'max' => static function($arg1, ...$args) { + if (! \is_array($arg1) && 0 === \count($args)){ + throw new IncorrectNumberOfFunctionParametersException(); + } + + return \max($arg1, ...$args); + }, + 'min' => static function($arg1, ...$args) { + if (! \is_array($arg1) && 0 === \count($args)){ + throw new IncorrectNumberOfFunctionParametersException(); + } + + return \min($arg1, ...$args); + }, 'octdec' => static fn($arg) => \octdec($arg), 'pi' => static fn() => M_PI, 'pow' => static fn($arg1, $arg2) => $arg1 ** $arg2, @@ -468,10 +492,10 @@ class MathExecutor */ protected function defaultVarValidation(string $variable, $value) : void { - if (! \is_scalar($value) && null !== $value) { + if (! \is_scalar($value) && ! \is_array($value) && null !== $value) { $type = \gettype($value); - throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar"); + throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar or array!"); } } } diff --git a/tests/MathTest.php b/tests/MathTest.php index e616721..c39eec7 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -328,10 +328,30 @@ class MathTest extends TestCase public function testFunctionUnlimitedParameters() : void { $calculator = new MathExecutor(); - $calculator->addFunction('max', static function($arg1, $arg2, ...$args) { - return \max($arg1, $arg2, ...$args); + $calculator->addFunction('give_me_an_array', static function() { + return [5, 3, 7, 9, 8]; }); - $this->assertEquals(\max(4, 6, 8.1, 2, 7), $calculator->execute('max(4,6,8.1,2,7)')); + $calculator->addFunction('my_avarage', static function($arg1, ...$args) { + if (\is_array($arg1)){ + return \array_sum($arg1) / \count($arg1); + } + + if (0 === \count($args)){ + throw new IncorrectNumberOfFunctionParametersException(); + } + $args = [$arg1, ...$args]; + + return \array_sum($args) / \count($args); + }); + $this->assertEquals(10, $calculator->execute('my_avarage(12,8,15,5)')); + $this->assertEquals(6.4, $calculator->execute('my_avarage(give_me_an_array())')); + $this->assertEquals(3, $calculator->execute('min(give_me_an_array())')); + $this->assertEquals(1, $calculator->execute('min(1,2,3)')); + $this->assertEquals(9, $calculator->execute('max(give_me_an_array())')); + $this->assertEquals(3, $calculator->execute('max(1,2,3)')); + $calculator->setVar('monthly_salaries', [100, 200, 300]); + $this->assertEquals([100, 200, 300], $calculator->execute('$monthly_salaries')); + $this->assertEquals(\max([100, 200, 300]), $calculator->execute('max($monthly_salaries)')); } public function testFunctionOptionalParameters() : void -- cgit v1.2.3