Start splitting some of the basic Statistical functions out into separate classes (#1888)

* Start splitting some of the basic Statistical functions out into separate classes containing just a few similar functions

* Splitting some of the basic Statistical functions out into separate classes containing just a few similar functions - MAX(), MAXA(), MIN() and MINA()

* Splitting some more of the basic Statistical functions out into separate classes containing just a few similar functions - StandardDeviations and Variances
This commit is contained in:
Mark Baker 2021-03-02 09:07:28 +01:00 committed by GitHub
parent 8721f795fc
commit 2eaf9b53aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1314 additions and 580 deletions

View File

@ -328,17 +328,17 @@ class Calculation
], ],
'AVEDEV' => [ 'AVEDEV' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'AVEDEV'], 'functionCall' => [Statistical\Averages::class, 'AVEDEV'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'AVERAGE' => [ 'AVERAGE' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'AVERAGE'], 'functionCall' => [Statistical\Averages::class, 'AVERAGE'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'AVERAGEA' => [ 'AVERAGEA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'AVERAGEA'], 'functionCall' => [Statistical\Averages::class, 'AVERAGEA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'AVERAGEIF' => [ 'AVERAGEIF' => [
@ -624,17 +624,17 @@ class Calculation
], ],
'COUNT' => [ 'COUNT' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'COUNT'], 'functionCall' => [Statistical\Counts::class, 'COUNT'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'COUNTA' => [ 'COUNTA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'COUNTA'], 'functionCall' => [Statistical\Counts::class, 'COUNTA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'COUNTBLANK' => [ 'COUNTBLANK' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'COUNTBLANK'], 'functionCall' => [Statistical\Counts::class, 'COUNTBLANK'],
'argumentCount' => '1', 'argumentCount' => '1',
], ],
'COUNTIF' => [ 'COUNTIF' => [
@ -1620,12 +1620,12 @@ class Calculation
], ],
'MAX' => [ 'MAX' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'MAX'], 'functionCall' => [Statistical\Maximum::class, 'MAX'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'MAXA' => [ 'MAXA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'MAXA'], 'functionCall' => [Statistical\Maximum::class, 'MAXA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'MAXIFS' => [ 'MAXIFS' => [
@ -1665,12 +1665,12 @@ class Calculation
], ],
'MIN' => [ 'MIN' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'MIN'], 'functionCall' => [Statistical\Minimum::class, 'MIN'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'MINA' => [ 'MINA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'MINA'], 'functionCall' => [Statistical\Minimum::class, 'MINA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'MINIFS' => [ 'MINIFS' => [
@ -2263,22 +2263,22 @@ class Calculation
], ],
'STDEV' => [ 'STDEV' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'STDEV'], 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'STDEV.S' => [ 'STDEV.S' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'STDEV'], 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'STDEV.P' => [ 'STDEV.P' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'STDEVP'], 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'STDEVA' => [ 'STDEVA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'STDEVA'], 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'STDEVP' => [ 'STDEVP' => [
@ -2524,32 +2524,32 @@ class Calculation
], ],
'VAR' => [ 'VAR' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARFunc'], 'functionCall' => [Statistical\Variances::class, 'VAR'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VAR.P' => [ 'VAR.P' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARP'], 'functionCall' => [Statistical\Variances::class, 'VARP'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VAR.S' => [ 'VAR.S' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARFunc'], 'functionCall' => [Statistical\Variances::class, 'VAR'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VARA' => [ 'VARA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARA'], 'functionCall' => [Statistical\Variances::class, 'VARA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VARP' => [ 'VARP' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARP'], 'functionCall' => [Statistical\Variances::class, 'VARP'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VARPA' => [ 'VARPA' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'VARPA'], 'functionCall' => [Statistical\Variances::class, 'VARPA'],
'argumentCount' => '1+', 'argumentCount' => '1+',
], ],
'VDB' => [ 'VDB' => [

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
class DAverage extends DatabaseAbstract class DAverage extends DatabaseAbstract
{ {
@ -38,7 +38,7 @@ class DAverage extends DatabaseAbstract
return null; return null;
} }
return Statistical::AVERAGE( return Averages::AVERAGE(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
class DCount extends DatabaseAbstract class DCount extends DatabaseAbstract
{ {
@ -36,7 +36,7 @@ class DCount extends DatabaseAbstract
{ {
$field = self::fieldExtract($database, $field); $field = self::fieldExtract($database, $field);
return Statistical::COUNT( return Counts::COUNT(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
class DCountA extends DatabaseAbstract class DCountA extends DatabaseAbstract
{ {
@ -35,7 +35,7 @@ class DCountA extends DatabaseAbstract
{ {
$field = self::fieldExtract($database, $field); $field = self::fieldExtract($database, $field);
return Statistical::COUNTA( return Counts::COUNTA(
self::getFilteredColumn($database, $field ?? 0, $criteria) self::getFilteredColumn($database, $field ?? 0, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
class DMax extends DatabaseAbstract class DMax extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DMax extends DatabaseAbstract
return null; return null;
} }
return Statistical::MAX( return Maximum::MAX(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
class DMin extends DatabaseAbstract class DMin extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DMin extends DatabaseAbstract
return null; return null;
} }
return Statistical::MIN( return Minimum::MIN(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
class DStDev extends DatabaseAbstract class DStDev extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DStDev extends DatabaseAbstract
return null; return null;
} }
return Statistical::STDEV( return StandardDeviations::STDEV(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
class DStDevP extends DatabaseAbstract class DStDevP extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DStDevP extends DatabaseAbstract
return null; return null;
} }
return Statistical::STDEVP( return StandardDeviations::STDEVP(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
class DVar extends DatabaseAbstract class DVar extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DVar extends DatabaseAbstract
return null; return null;
} }
return Statistical::VARFunc( return Variances::VAR(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Database; namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
class DVarP extends DatabaseAbstract class DVarP extends DatabaseAbstract
{ {
@ -39,7 +39,7 @@ class DVarP extends DatabaseAbstract
return null; return null;
} }
return Statistical::VARP( return Variances::VARP(
self::getFilteredColumn($database, $field, $criteria) self::getFilteredColumn($database, $field, $criteria)
); );
} }

View File

@ -1222,27 +1222,27 @@ class MathTrig
$aArgs = self::filterFormulaArgs($cellReference, $aArgs); $aArgs = self::filterFormulaArgs($cellReference, $aArgs);
switch ($subtotal) { switch ($subtotal) {
case 1: case 1:
return Statistical::AVERAGE($aArgs); return Statistical\Averages::AVERAGE($aArgs);
case 2: case 2:
return Statistical::COUNT($aArgs); return Statistical\Counts::COUNT($aArgs);
case 3: case 3:
return Statistical::COUNTA($aArgs); return Statistical\Counts::COUNTA($aArgs);
case 4: case 4:
return Statistical::MAX($aArgs); return Statistical\Maximum::MAX($aArgs);
case 5: case 5:
return Statistical::MIN($aArgs); return Statistical\Minimum::MIN($aArgs);
case 6: case 6:
return self::PRODUCT($aArgs); return self::PRODUCT($aArgs);
case 7: case 7:
return Statistical::STDEV($aArgs); return Statistical\StandardDeviations::STDEV($aArgs);
case 8: case 8:
return Statistical::STDEVP($aArgs); return Statistical\StandardDeviations::STDEVP($aArgs);
case 9: case 9:
return self::SUM($aArgs); return self::SUM($aArgs);
case 10: case 10:
return Statistical::VARFunc($aArgs); return Statistical\Variances::VAR($aArgs);
case 11: case 11:
return Statistical::VARP($aArgs); return Statistical\Variances::VARP($aArgs);
} }
} }

View File

@ -2,8 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Calculation; namespace PhpOffice\PhpSpreadsheet\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend; use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend;
class Statistical class Statistical
@ -520,48 +526,6 @@ class Statistical
return Functions::NULL(); return Functions::NULL();
} }
/**
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
* OpenOffice Calc always counts Booleans.
* Gnumeric never counts Booleans.
*
* @param mixed $arg
* @param mixed $k
*
* @return int|mixed
*/
private static function testAcceptedBoolean($arg, $k)
{
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
return $arg;
}
/**
* @param mixed $arg
* @param mixed $k
*
* @return bool
*/
private static function isAcceptedCountable($arg, $k)
{
if (
((is_numeric($arg)) && (!is_string($arg))) ||
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
) {
return true;
}
return false;
}
/** /**
* AVEDEV. * AVEDEV.
* *
@ -571,45 +535,18 @@ class Statistical
* Excel Function: * Excel Function:
* AVEDEV(value1[,value2[, ...]]) * AVEDEV(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Averages::AVEDEV()
* Use the AVEDEV() method in the Statistical\Averages class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function AVEDEV(...$args) public static function AVEDEV(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); return Averages::AVEDEV(...$args);
// Return value
$returnValue = 0;
$aMean = self::AVERAGE(...$args);
if ($aMean === Functions::DIV0()) {
return Functions::NAN();
} elseif ($aMean === Functions::VALUE()) {
return Functions::VALUE();
}
$aCount = 0;
foreach ($aArgs as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
return Functions::VALUE();
}
if (self::isAcceptedCountable($arg, $k)) {
$returnValue += abs($arg - $aMean);
++$aCount;
}
}
// Return
if ($aCount === 0) {
return Functions::DIV0();
}
return $returnValue / $aCount;
} }
/** /**
@ -620,35 +557,18 @@ class Statistical
* Excel Function: * Excel Function:
* AVERAGE(value1[,value2[, ...]]) * AVERAGE(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Averages::AVERAGE()
* Use the AVERAGE() method in the Statistical\Averages class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function AVERAGE(...$args) public static function AVERAGE(...$args)
{ {
$returnValue = $aCount = 0; return Averages::AVERAGE(...$args);
// Loop through arguments
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
return Functions::VALUE();
}
if (self::isAcceptedCountable($arg, $k)) {
$returnValue += $arg;
++$aCount;
}
}
// Return
if ($aCount > 0) {
return $returnValue / $aCount;
}
return Functions::DIV0();
} }
/** /**
@ -659,39 +579,18 @@ class Statistical
* Excel Function: * Excel Function:
* AVERAGEA(value1[,value2[, ...]]) * AVERAGEA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Averages::AVERAGEA()
* Use the AVERAGEA() method in the Statistical\Averages class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function AVERAGEA(...$args) public static function AVERAGEA(...$args)
{ {
$returnValue = null; return Averages::AVERAGEA(...$args);
$aCount = 0;
// Loop through arguments
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
if (
(is_bool($arg)) &&
(!Functions::isMatrixValue($k))
) {
} else {
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
$returnValue += $arg;
++$aCount;
}
}
}
if ($aCount > 0) {
return $returnValue / $aCount;
}
return Functions::DIV0();
} }
/** /**
@ -715,7 +614,7 @@ class Statistical
*/ */
public static function AVERAGEIF($range, $condition, $averageRange = []) public static function AVERAGEIF($range, $condition, $averageRange = [])
{ {
return Statistical\Conditional::AVERAGEIF($range, $condition, $averageRange); return Conditional::AVERAGEIF($range, $condition, $averageRange);
} }
/** /**
@ -1026,27 +925,18 @@ class Statistical
* Excel Function: * Excel Function:
* COUNT(value1[,value2[, ...]]) * COUNT(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Counts::COUNT()
* Use the COUNT() method in the Statistical\Counts class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return int * @return int
*/ */
public static function COUNT(...$args) public static function COUNT(...$args)
{ {
$returnValue = 0; return Counts::COUNT(...$args);
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
foreach ($aArgs as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if (self::isAcceptedCountable($arg, $k)) {
++$returnValue;
}
}
return $returnValue;
} }
/** /**
@ -1057,24 +947,18 @@ class Statistical
* Excel Function: * Excel Function:
* COUNTA(value1[,value2[, ...]]) * COUNTA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Counts::COUNTA()
* Use the COUNTA() method in the Statistical\Counts class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return int * @return int
*/ */
public static function COUNTA(...$args) public static function COUNTA(...$args)
{ {
$returnValue = 0; return Counts::COUNTA(...$args);
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
foreach ($aArgs as $k => $arg) {
// Nulls are counted if literals, but not if cell values
if ($arg !== null || (!Functions::isCellValue($k))) {
++$returnValue;
}
}
return $returnValue;
} }
/** /**
@ -1085,24 +969,18 @@ class Statistical
* Excel Function: * Excel Function:
* COUNTBLANK(value1[,value2[, ...]]) * COUNTBLANK(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Counts::COUNTBLANK()
* Use the COUNTBLANK() method in the Statistical\Counts class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return int * @return int
*/ */
public static function COUNTBLANK(...$args) public static function COUNTBLANK(...$args)
{ {
$returnValue = 0; return Counts::COUNTBLANK(...$args);
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a blank cell?
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
++$returnValue;
}
}
return $returnValue;
} }
/** /**
@ -1125,7 +1003,7 @@ class Statistical
*/ */
public static function COUNTIF($range, $condition) public static function COUNTIF($range, $condition)
{ {
return Statistical\Conditional::COUNTIF($range, $condition); return Conditional::COUNTIF($range, $condition);
} }
/** /**
@ -1147,7 +1025,7 @@ class Statistical
*/ */
public static function COUNTIFS(...$args) public static function COUNTIFS(...$args)
{ {
return Statistical\Conditional::COUNTIFS(...$args); return Conditional::COUNTIFS(...$args);
} }
/** /**
@ -1325,7 +1203,7 @@ class Statistical
// Return value // Return value
$returnValue = null; $returnValue = null;
$aMean = self::AVERAGE($aArgs); $aMean = Averages::AVERAGE($aArgs);
if ($aMean != Functions::DIV0()) { if ($aMean != Functions::DIV0()) {
$aCount = -1; $aCount = -1;
foreach ($aArgs as $k => $arg) { foreach ($aArgs as $k => $arg) {
@ -1711,8 +1589,8 @@ class Statistical
$aMean = MathTrig::PRODUCT($aArgs); $aMean = MathTrig::PRODUCT($aArgs);
if (is_numeric($aMean) && ($aMean > 0)) { if (is_numeric($aMean) && ($aMean > 0)) {
$aCount = self::COUNT($aArgs); $aCount = Counts::COUNT($aArgs);
if (self::MIN($aArgs) > 0) { if (Minimum::MIN($aArgs) > 0) {
return $aMean ** (1 / $aCount); return $aMean ** (1 / $aCount);
} }
} }
@ -1772,7 +1650,7 @@ class Statistical
// Loop through arguments // Loop through arguments
$aArgs = Functions::flattenArray($args); $aArgs = Functions::flattenArray($args);
if (self::MIN($aArgs) < 0) { if (Minimum::MIN($aArgs) < 0) {
return Functions::NAN(); return Functions::NAN();
} }
$aCount = 0; $aCount = 0;
@ -1883,8 +1761,8 @@ class Statistical
public static function KURT(...$args) public static function KURT(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); $aArgs = Functions::flattenArrayIndexed($args);
$mean = self::AVERAGE($aArgs); $mean = Averages::AVERAGE($aArgs);
$stdDev = self::STDEV($aArgs); $stdDev = StandardDeviations::STDEV($aArgs);
if ($stdDev > 0) { if ($stdDev > 0) {
$count = $summer = 0; $count = $summer = 0;
@ -1941,7 +1819,7 @@ class Statistical
$mArgs[] = $arg; $mArgs[] = $arg;
} }
} }
$count = self::COUNT($mArgs); $count = Counts::COUNT($mArgs);
--$entry; --$entry;
if (($entry < 0) || ($entry >= $count) || ($count == 0)) { if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
return Functions::NAN(); return Functions::NAN();
@ -2184,30 +2062,18 @@ class Statistical
* Excel Function: * Excel Function:
* MAX(value1[,value2[, ...]]) * MAX(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Maximum::MAX()
* Use the MAX() method in the Statistical\Maximum class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float * @return float
*/ */
public static function MAX(...$args) public static function MAX(...$args)
{ {
$returnValue = null; return Maximum::MAX(...$args);
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if (($returnValue === null) || ($arg > $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
} }
/** /**
@ -2218,35 +2084,18 @@ class Statistical
* Excel Function: * Excel Function:
* MAXA(value1[,value2[, ...]]) * MAXA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Maximum::MAXA()
* Use the MAXA() method in the Statistical\Maximum class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float * @return float
*/ */
public static function MAXA(...$args) public static function MAXA(...$args)
{ {
$returnValue = null; return Maximum::MAXA(...$args);
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
if (($returnValue === null) || ($arg > $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
} }
/** /**
@ -2321,30 +2170,18 @@ class Statistical
* Excel Function: * Excel Function:
* MIN(value1[,value2[, ...]]) * MIN(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Minimum::MIN()
* Use the MIN() method in the Statistical\Minimum class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float * @return float
*/ */
public static function MIN(...$args) public static function MIN(...$args)
{ {
$returnValue = null; return Minimum::MIN(...$args);
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if (($returnValue === null) || ($arg < $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
} }
/** /**
@ -2355,35 +2192,18 @@ class Statistical
* Excel Function: * Excel Function:
* MINA(value1[,value2[, ...]]) * MINA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Minimum::MINA()
* Use the MINA() method in the Statistical\Minimum class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float * @return float
*/ */
public static function MINA(...$args) public static function MINA(...$args)
{ {
$returnValue = null; return Minimum::MINA(...$args);
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
if (($returnValue === null) || ($arg < $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
} }
/** /**
@ -2688,7 +2508,7 @@ class Statistical
$mValueCount = count($mArgs); $mValueCount = count($mArgs);
if ($mValueCount > 0) { if ($mValueCount > 0) {
sort($mArgs); sort($mArgs);
$count = self::COUNT($mArgs); $count = Counts::COUNT($mArgs);
$index = $entry * ($count - 1); $index = $entry * ($count - 1);
$iBase = floor($index); $iBase = floor($index);
if ($index == $iBase) { if ($index == $iBase) {
@ -2775,7 +2595,7 @@ class Statistical
*/ */
public static function PERMUT($numObjs, $numInSet) public static function PERMUT($numObjs, $numInSet)
{ {
return Statistical\Permutations::PERMUT($numObjs, $numInSet); return Permutations::PERMUT($numObjs, $numInSet);
} }
/** /**
@ -2930,8 +2750,8 @@ class Statistical
public static function SKEW(...$args) public static function SKEW(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); $aArgs = Functions::flattenArrayIndexed($args);
$mean = self::AVERAGE($aArgs); $mean = Averages::AVERAGE($aArgs);
$stdDev = self::STDEV($aArgs); $stdDev = StandardDeviations::STDEV($aArgs);
$count = $summer = 0; $count = $summer = 0;
// Loop through arguments // Loop through arguments
@ -3015,7 +2835,7 @@ class Statistical
$mArgs[] = $arg; $mArgs[] = $arg;
} }
} }
$count = self::COUNT($mArgs); $count = Counts::COUNT($mArgs);
--$entry; --$entry;
if (($entry < 0) || ($entry >= $count) || ($count == 0)) { if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
return Functions::NAN(); return Functions::NAN();
@ -3065,45 +2885,18 @@ class Statistical
* Excel Function: * Excel Function:
* STDEV(value1[,value2[, ...]]) * STDEV(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\StandardDeviations::STDEV()
* Use the STDEV() method in the Statistical\StandardDeviations class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
public static function STDEV(...$args) public static function STDEV(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); return StandardDeviations::STDEV(...$args);
// Return value
$returnValue = null;
$aMean = self::AVERAGE($aArgs);
if ($aMean !== null) {
$aCount = -1;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if ($returnValue === null) {
$returnValue = ($arg - $aMean) ** 2;
} else {
$returnValue += ($arg - $aMean) ** 2;
}
++$aCount;
}
}
// Return
if (($aCount > 0) && ($returnValue >= 0)) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
} }
/** /**
@ -3114,48 +2907,18 @@ class Statistical
* Excel Function: * Excel Function:
* STDEVA(value1[,value2[, ...]]) * STDEVA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\StandardDeviations::STDEVA()
* Use the STDEVA() method in the Statistical\StandardDeviations class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function STDEVA(...$args) public static function STDEVA(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); return StandardDeviations::STDEVA(...$args);
$returnValue = null;
$aMean = self::AVERAGEA($aArgs);
if ($aMean !== null) {
$aCount = -1;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
(!Functions::isMatrixValue($k))
) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
if ($returnValue === null) {
$returnValue = ($arg - $aMean) ** 2;
} else {
$returnValue += ($arg - $aMean) ** 2;
}
++$aCount;
}
}
}
if (($aCount > 0) && ($returnValue >= 0)) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
} }
/** /**
@ -3166,43 +2929,18 @@ class Statistical
* Excel Function: * Excel Function:
* STDEVP(value1[,value2[, ...]]) * STDEVP(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\StandardDeviations::STDEVP()
* Use the STDEVP() method in the Statistical\StandardDeviations class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function STDEVP(...$args) public static function STDEVP(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); return StandardDeviations::STDEVP(...$args);
$returnValue = null;
$aMean = self::AVERAGE($aArgs);
if ($aMean !== null) {
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if ($returnValue === null) {
$returnValue = ($arg - $aMean) ** 2;
} else {
$returnValue += ($arg - $aMean) ** 2;
}
++$aCount;
}
}
if (($aCount > 0) && ($returnValue >= 0)) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
} }
/** /**
@ -3213,48 +2951,18 @@ class Statistical
* Excel Function: * Excel Function:
* STDEVPA(value1[,value2[, ...]]) * STDEVPA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\StandardDeviations::STDEVPA()
* Use the STDEVPA() method in the Statistical\StandardDeviations class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string * @return float|string
*/ */
public static function STDEVPA(...$args) public static function STDEVPA(...$args)
{ {
$aArgs = Functions::flattenArrayIndexed($args); return StandardDeviations::STDEVPA(...$args);
$returnValue = null;
$aMean = self::AVERAGEA($aArgs);
if ($aMean !== null) {
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
(!Functions::isMatrixValue($k))
) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
if ($returnValue === null) {
$returnValue = ($arg - $aMean) ** 2;
} else {
$returnValue += ($arg - $aMean) ** 2;
}
++$aCount;
}
}
}
if (($aCount > 0) && ($returnValue >= 0)) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
} }
/** /**
@ -3472,14 +3180,14 @@ class Statistical
$mArgs[] = $arg; $mArgs[] = $arg;
} }
} }
$discard = floor(self::COUNT($mArgs) * $percent / 2); $discard = floor(Counts::COUNT($mArgs) * $percent / 2);
sort($mArgs); sort($mArgs);
for ($i = 0; $i < $discard; ++$i) { for ($i = 0; $i < $discard; ++$i) {
array_pop($mArgs); array_pop($mArgs);
array_shift($mArgs); array_shift($mArgs);
} }
return self::AVERAGE($mArgs); return Averages::AVERAGE($mArgs);
} }
return Functions::VALUE(); return Functions::VALUE();
@ -3493,38 +3201,18 @@ class Statistical
* Excel Function: * Excel Function:
* VAR(value1[,value2[, ...]]) * VAR(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string (string if result is an error) * @return float|string (string if result is an error)
*
*@see Statistical\Variances::VAR()
* Use the VAR() method in the Statistical\Variances class instead
*/ */
public static function VARFunc(...$args) public static function VARFunc(...$args)
{ {
$returnValue = Functions::DIV0(); return Variances::VAR(...$args);
$summerA = $summerB = 0;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
$aCount = 0;
foreach ($aArgs as $arg) {
if (is_bool($arg)) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
if ($aCount > 1) {
$summerA *= $aCount;
$summerB *= $summerB;
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
}
return $returnValue;
} }
/** /**
@ -3535,51 +3223,18 @@ class Statistical
* Excel Function: * Excel Function:
* VARA(value1[,value2[, ...]]) * VARA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Variances::VARA()
* Use the VARA() method in the Statistical\Variances class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string (string if result is an error) * @return float|string (string if result is an error)
*/ */
public static function VARA(...$args) public static function VARA(...$args)
{ {
$returnValue = Functions::DIV0(); return Variances::VARA(...$args);
$summerA = $summerB = 0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if (
(is_string($arg)) &&
(Functions::isValue($k))
) {
return Functions::VALUE();
} elseif (
(is_string($arg)) &&
(!Functions::isMatrixValue($k))
) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
}
if ($aCount > 1) {
$summerA *= $aCount;
$summerB *= $summerB;
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
}
return $returnValue;
} }
/** /**
@ -3590,39 +3245,18 @@ class Statistical
* Excel Function: * Excel Function:
* VARP(value1[,value2[, ...]]) * VARP(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Variances::VARP()
* Use the VARP() method in the Statistical\Variances class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string (string if result is an error) * @return float|string (string if result is an error)
*/ */
public static function VARP(...$args) public static function VARP(...$args)
{ {
// Return value return Variances::VARP(...$args);
$returnValue = Functions::DIV0();
$summerA = $summerB = 0;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
$aCount = 0;
foreach ($aArgs as $arg) {
if (is_bool($arg)) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
if ($aCount > 0) {
$summerA *= $aCount;
$summerB *= $summerB;
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
}
return $returnValue;
} }
/** /**
@ -3633,51 +3267,18 @@ class Statistical
* Excel Function: * Excel Function:
* VARPA(value1[,value2[, ...]]) * VARPA(value1[,value2[, ...]])
* *
* @Deprecated 1.17.0
*
* @see Statistical\Variances::VARPA()
* Use the VARPA() method in the Statistical\Variances class instead
*
* @param mixed ...$args Data values * @param mixed ...$args Data values
* *
* @return float|string (string if result is an error) * @return float|string (string if result is an error)
*/ */
public static function VARPA(...$args) public static function VARPA(...$args)
{ {
$returnValue = Functions::DIV0(); return Variances::VARPA(...$args);
$summerA = $summerB = 0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if (
(is_string($arg)) &&
(Functions::isValue($k))
) {
return Functions::VALUE();
} elseif (
(is_string($arg)) &&
(!Functions::isMatrixValue($k))
) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
}
if ($aCount > 0) {
$summerA *= $aCount;
$summerB *= $summerB;
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
}
return $returnValue;
} }
/** /**
@ -3734,10 +3335,10 @@ class Statistical
$sigma = Functions::flattenSingleValue($sigma); $sigma = Functions::flattenSingleValue($sigma);
if ($sigma === null) { if ($sigma === null) {
$sigma = self::STDEV($dataSet); $sigma = StandardDeviations::STDEV($dataSet);
} }
$n = count($dataSet); $n = count($dataSet);
return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n))); return 1 - self::NORMSDIST((Averages::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
} }
} }

View File

@ -0,0 +1,50 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
abstract class AggregateBase
{
/**
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
* OpenOffice Calc always counts Booleans.
* Gnumeric never counts Booleans.
*
* @param mixed $arg
* @param mixed $k
*
* @return int|mixed
*/
protected static function testAcceptedBoolean($arg, $k)
{
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
return $arg;
}
/**
* @param mixed $arg
* @param mixed $k
*
* @return bool
*/
protected static function isAcceptedCountable($arg, $k)
{
if (
((is_numeric($arg)) && (!is_string($arg))) ||
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,137 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Averages extends AggregateBase
{
/**
* AVEDEV.
*
* Returns the average of the absolute deviations of data points from their mean.
* AVEDEV is a measure of the variability in a data set.
*
* Excel Function:
* AVEDEV(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function AVEDEV(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
// Return value
$returnValue = 0;
$aMean = self::AVERAGE(...$args);
if ($aMean === Functions::DIV0()) {
return Functions::NAN();
} elseif ($aMean === Functions::VALUE()) {
return Functions::VALUE();
}
$aCount = 0;
foreach ($aArgs as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
return Functions::VALUE();
}
if (self::isAcceptedCountable($arg, $k)) {
$returnValue += abs($arg - $aMean);
++$aCount;
}
}
// Return
if ($aCount === 0) {
return Functions::DIV0();
}
return $returnValue / $aCount;
}
/**
* AVERAGE.
*
* Returns the average (arithmetic mean) of the arguments
*
* Excel Function:
* AVERAGE(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function AVERAGE(...$args)
{
$returnValue = $aCount = 0;
// Loop through arguments
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
return Functions::VALUE();
}
if (self::isAcceptedCountable($arg, $k)) {
$returnValue += $arg;
++$aCount;
}
}
// Return
if ($aCount > 0) {
return $returnValue / $aCount;
}
return Functions::DIV0();
}
/**
* AVERAGEA.
*
* Returns the average of its arguments, including numbers, text, and logical values
*
* Excel Function:
* AVERAGEA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function AVERAGEA(...$args)
{
$returnValue = null;
$aCount = 0;
// Loop through arguments
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
} else {
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
if (is_bool($arg)) {
$arg = (int) $arg;
} elseif (is_string($arg)) {
$arg = 0;
}
$returnValue += $arg;
++$aCount;
}
}
}
if ($aCount > 0) {
return $returnValue / $aCount;
}
return Functions::DIV0();
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Counts extends AggregateBase
{
/**
* COUNT.
*
* Counts the number of cells that contain numbers within the list of arguments
*
* Excel Function:
* COUNT(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNT(...$args)
{
$returnValue = 0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
foreach ($aArgs as $k => $arg) {
$arg = self::testAcceptedBoolean($arg, $k);
// Is it a numeric value?
// Strings containing numeric values are only counted if they are string literals (not cell values)
// and then only in MS Excel and in Open Office, not in Gnumeric
if (self::isAcceptedCountable($arg, $k)) {
++$returnValue;
}
}
return $returnValue;
}
/**
* COUNTA.
*
* Counts the number of cells that are not empty within the list of arguments
*
* Excel Function:
* COUNTA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNTA(...$args)
{
$returnValue = 0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
foreach ($aArgs as $k => $arg) {
// Nulls are counted if literals, but not if cell values
if ($arg !== null || (!Functions::isCellValue($k))) {
++$returnValue;
}
}
return $returnValue;
}
/**
* COUNTBLANK.
*
* Counts the number of empty cells within the list of arguments
*
* Excel Function:
* COUNTBLANK(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNTBLANK(...$args)
{
$returnValue = 0;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a blank cell?
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
++$returnValue;
}
}
return $returnValue;
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
abstract class MaxMinBase
{
protected static function datatypeAdjustmentAllowStrings($value)
{
if (is_bool($value)) {
return (int) $value;
} elseif (is_string($value)) {
return 0;
}
return $value;
}
}

View File

@ -0,0 +1,78 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Maximum extends MaxMinBase
{
/**
* MAX.
*
* MAX returns the value of the element of the values passed that has the highest value,
* with negative numbers considered smaller than positive numbers.
*
* Excel Function:
* MAX(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float
*/
public static function MAX(...$args)
{
$returnValue = null;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if (($returnValue === null) || ($arg > $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
}
/**
* MAXA.
*
* Returns the greatest value in a list of arguments, including numbers, text, and logical values
*
* Excel Function:
* MAXA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float
*/
public static function MAXA(...$args)
{
$returnValue = null;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
if (($returnValue === null) || ($arg > $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
}
}

View File

@ -0,0 +1,78 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Minimum extends MaxMinBase
{
/**
* MIN.
*
* MIN returns the value of the element of the values passed that has the smallest value,
* with negative numbers considered smaller than positive numbers.
*
* Excel Function:
* MIN(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float
*/
public static function MIN(...$args)
{
$returnValue = null;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
if (($returnValue === null) || ($arg < $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
}
/**
* MINA.
*
* Returns the smallest value in a list of arguments, including numbers, text, and logical values
*
* Excel Function:
* MINA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float
*/
public static function MINA(...$args)
{
$returnValue = null;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
foreach ($aArgs as $arg) {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
if (($returnValue === null) || ($arg < $returnValue)) {
$returnValue = $arg;
}
}
}
if ($returnValue === null) {
return 0;
}
return $returnValue;
}
}

View File

@ -0,0 +1,181 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class StandardDeviations extends VarianceBase
{
/**
* STDEV.
*
* Estimates standard deviation based on a sample. The standard deviation is a measure of how
* widely values are dispersed from the average value (the mean).
*
* Excel Function:
* STDEV(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function STDEV(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
$aMean = Averages::AVERAGE($aArgs);
if (!is_string($aMean)) {
$returnValue = 0.0;
$aCount = -1;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$returnValue += ($arg - $aMean) ** 2;
++$aCount;
}
}
if ($aCount > 0) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
}
/**
* STDEVA.
*
* Estimates standard deviation based on a sample, including numbers, text, and logical values
*
* Excel Function:
* STDEVA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVA(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
$aMean = Averages::AVERAGEA($aArgs);
if (!is_string($aMean)) {
$returnValue = 0.0;
$aCount = -1;
foreach ($aArgs as $k => $arg) {
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
$returnValue += ($arg - $aMean) ** 2;
++$aCount;
}
}
}
if ($aCount > 0) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
}
/**
* STDEVP.
*
* Calculates standard deviation based on the entire population
*
* Excel Function:
* STDEVP(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVP(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
$aMean = Averages::AVERAGE($aArgs);
if (!is_string($aMean)) {
$returnValue = 0.0;
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if (
(is_bool($arg)) &&
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
) {
$arg = (int) $arg;
}
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$returnValue += ($arg - $aMean) ** 2;
++$aCount;
}
}
if ($aCount > 0) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
}
/**
* STDEVPA.
*
* Calculates standard deviation based on the entire population, including numbers, text, and logical values
*
* Excel Function:
* STDEVPA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVPA(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
$aMean = Averages::AVERAGEA($aArgs);
if (!is_string($aMean)) {
$returnValue = 0.0;
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
$returnValue += ($arg - $aMean) ** 2;
++$aCount;
}
}
}
if ($aCount > 0) {
return sqrt($returnValue / $aCount);
}
}
return Functions::DIV0();
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
abstract class VarianceBase
{
protected static function datatypeAdjustmentAllowStrings($value)
{
if (is_bool($value)) {
return (int) $value;
} elseif (is_string($value)) {
return 0;
}
return $value;
}
protected static function datatypeAdjustmentBooleans($value)
{
if (is_bool($value)) {
return (int) $value;
}
return $value;
}
}

View File

@ -0,0 +1,183 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Variances extends VarianceBase
{
/**
* VAR.
*
* Estimates variance based on a sample.
*
* Excel Function:
* VAR(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VAR(...$args)
{
$returnValue = Functions::DIV0();
$summerA = $summerB = 0.0;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
$aCount = 0;
foreach ($aArgs as $arg) {
$arg = self::datatypeAdjustmentBooleans($arg);
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
if ($aCount > 1) {
$summerA *= $aCount;
$summerB *= $summerB;
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
}
return $returnValue;
}
/**
* VARA.
*
* Estimates variance based on a sample, including numbers, text, and logical values
*
* Excel Function:
* VARA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARA(...$args)
{
$returnValue = Functions::DIV0();
$summerA = $summerB = 0.0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if ((is_string($arg)) && (Functions::isValue($k))) {
return Functions::VALUE();
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
}
if ($aCount > 1) {
$summerA *= $aCount;
$summerB *= $summerB;
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
}
return $returnValue;
}
/**
* VARP.
*
* Calculates variance based on the entire population
*
* Excel Function:
* VARP(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARP(...$args)
{
// Return value
$returnValue = Functions::DIV0();
$summerA = $summerB = 0.0;
// Loop through arguments
$aArgs = Functions::flattenArray($args);
$aCount = 0;
foreach ($aArgs as $arg) {
$arg = self::datatypeAdjustmentBooleans($arg);
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
if ($aCount > 0) {
$summerA *= $aCount;
$summerB *= $summerB;
return ($summerA - $summerB) / ($aCount * $aCount);
}
return $returnValue;
}
/**
* VARPA.
*
* Calculates variance based on the entire population, including numbers, text, and logical values
*
* Excel Function:
* VARPA(value1[,value2[, ...]])
*
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARPA(...$args)
{
$returnValue = Functions::DIV0();
$summerA = $summerB = 0.0;
// Loop through arguments
$aArgs = Functions::flattenArrayIndexed($args);
$aCount = 0;
foreach ($aArgs as $k => $arg) {
if ((is_string($arg)) && (Functions::isValue($k))) {
return Functions::VALUE();
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
} else {
// Is it a numeric value?
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
$arg = self::datatypeAdjustmentAllowStrings($arg);
$summerA += ($arg * $arg);
$summerB += $arg;
++$aCount;
}
}
}
if ($aCount > 0) {
$summerA *= $aCount;
$summerB *= $summerB;
return ($summerA - $summerB) / ($aCount * $aCount);
}
return $returnValue;
}
}

View File

@ -24,7 +24,7 @@ class Tcpdf extends Pdf
* *
* @param string $orientation Page orientation * @param string $orientation Page orientation
* @param string $unit Unit measure * @param string $unit Unit measure
* @param string $paperSize Paper size * @param array|string $paperSize Paper size
* *
* @return \TCPDF implementation * @return \TCPDF implementation
*/ */

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class StDevATest extends TestCase
{
/**
* @dataProvider providerSTDEVA
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testSTDEVA($expectedResult, $values): void
{
$result = Statistical::STDEVA($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerSTDEVA()
{
return require 'tests/data/Calculation/Statistical/STDEVA.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class StDevPATest extends TestCase
{
/**
* @dataProvider providerSTDEVPA
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testSTDEVPA($expectedResult, $values): void
{
$result = Statistical::STDEVPA($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerSTDEVPA()
{
return require 'tests/data/Calculation/Statistical/STDEVPA.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class StDevPTest extends TestCase
{
/**
* @dataProvider providerSTDEVP
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testSTDEVP($expectedResult, $values): void
{
$result = Statistical::STDEVP($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerSTDEVP()
{
return require 'tests/data/Calculation/Statistical/STDEVP.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class StDevTest extends TestCase
{
/**
* @dataProvider providerSTDEV
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testSTDEV($expectedResult, $values): void
{
$result = Statistical::STDEV($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerSTDEV()
{
return require 'tests/data/Calculation/Statistical/STDEV.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class VarATest extends TestCase
{
/**
* @dataProvider providerVARA
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testVARA($expectedResult, $values): void
{
$result = Statistical::VARA($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerVARA()
{
return require 'tests/data/Calculation/Statistical/VARA.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class VarPATest extends TestCase
{
/**
* @dataProvider providerVARPA
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testVARPA($expectedResult, $values): void
{
$result = Statistical::VARPA($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerVARPA()
{
return require 'tests/data/Calculation/Statistical/VARPA.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class VarPTest extends TestCase
{
/**
* @dataProvider providerVARP
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testVARP($expectedResult, $values): void
{
$result = Statistical::VARP($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerVARP()
{
return require 'tests/data/Calculation/Statistical/VARP.php';
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
use PHPUnit\Framework\TestCase;
class VarTest extends TestCase
{
/**
* @dataProvider providerVAR
*
* @param mixed $expectedResult
* @param mixed $values
*/
public function testVAR($expectedResult, $values): void
{
$result = Statistical::VARFunc($values);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
public function providerVAR()
{
return require 'tests/data/Calculation/Statistical/VAR.php';
}
}

View File

@ -0,0 +1,12 @@
<?php
return [
[
27.463915719843,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
[
'#DIV/0!',
['A', 'B', 'C'],
],
];

View File

@ -0,0 +1,12 @@
<?php
return [
[
27.463915719843,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
[
'#DIV/0!',
[],
],
];

View File

@ -0,0 +1,12 @@
<?php
return [
[
26.0545581424825,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
[
'#DIV/0!',
['A', 'B', 'C'],
],
];

View File

@ -0,0 +1,12 @@
<?php
return [
[
26.0545581424825,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
[
'#DIV/0!',
[],
],
];

View File

@ -0,0 +1,8 @@
<?php
return [
[
754.266666666667,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
];

View File

@ -0,0 +1,8 @@
<?php
return [
[
754.266666666667,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
];

View File

@ -0,0 +1,8 @@
<?php
return [
[
678.84,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
];

View File

@ -0,0 +1,8 @@
<?php
return [
[
678.84,
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
],
];