ref #65, new formula functions: COVARIANCE.S and STDEVPA

pull/2/head
xuri 3 years ago
parent c1940c2a1e
commit 396cf99d45
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

@ -393,6 +393,7 @@ type formulaFuncs struct {
// COUPPCD // COUPPCD
// COVAR // COVAR
// COVARIANCE.P // COVARIANCE.P
// COVARIANCE.S
// CRITBINOM // CRITBINOM
// CSC // CSC
// CSCH // CSCH
@ -645,6 +646,7 @@ type formulaFuncs struct {
// STDEV.S // STDEV.S
// STDEVA // STDEVA
// STDEVP // STDEVP
// STDEVPA
// SUBSTITUTE // SUBSTITUTE
// SUM // SUM
// SUMIF // SUMIF
@ -6851,14 +6853,11 @@ func (fn *formulaFuncs) CONFIDENCEdotT(argsList *list.List) formulaArg {
}, size.Number/2, size.Number) / math.Sqrt(size.Number)) }, size.Number/2, size.Number) / math.Sqrt(size.Number))
} }
// COVAR function calculates the covariance of two supplied sets of values. The // covar is an implementation of the formula functions COVAR, COVARIANCE.P and
// syntax of the function is: // COVARIANCE.S.
// func (fn *formulaFuncs) covar(name string, argsList *list.List) formulaArg {
// COVAR(array1,array2)
//
func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
if argsList.Len() != 2 { if argsList.Len() != 2 {
return newErrorFormulaArg(formulaErrorVALUE, "COVAR requires 2 arguments") return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
} }
array1 := argsList.Front().Value.(formulaArg) array1 := argsList.Front().Value.(formulaArg)
array2 := argsList.Back().Value.(formulaArg) array2 := argsList.Back().Value.(formulaArg)
@ -6881,19 +6880,37 @@ func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
} }
result += (arg1.Number - mean1.Number) * (arg2.Number - mean2.Number) result += (arg1.Number - mean1.Number) * (arg2.Number - mean2.Number)
} }
if name == "COVARIANCE.S" {
return newNumberFormulaArg(result / float64(n-skip-1))
}
return newNumberFormulaArg(result / float64(n-skip)) return newNumberFormulaArg(result / float64(n-skip))
} }
// COVAR function calculates the covariance of two supplied sets of values. The
// syntax of the function is:
//
// COVAR(array1,array2)
//
func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
return fn.covar("COVAR", argsList)
}
// COVARIANCEdotP function calculates the population covariance of two supplied // COVARIANCEdotP function calculates the population covariance of two supplied
// sets of values. The syntax of the function is: // sets of values. The syntax of the function is:
// //
// COVARIANCE.P(array1,array2) // COVARIANCE.P(array1,array2)
// //
func (fn *formulaFuncs) COVARIANCEdotP(argsList *list.List) formulaArg { func (fn *formulaFuncs) COVARIANCEdotP(argsList *list.List) formulaArg {
if argsList.Len() != 2 { return fn.covar("COVARIANCE.P", argsList)
return newErrorFormulaArg(formulaErrorVALUE, "COVARIANCE.P requires 2 arguments") }
}
return fn.COVAR(argsList) // COVARIANCEdotS function calculates the sample covariance of two supplied
// sets of values. The syntax of the function is:
//
// COVARIANCE.S(array1,array2)
//
func (fn *formulaFuncs) COVARIANCEdotS(argsList *list.List) formulaArg {
return fn.covar("COVARIANCE.S", argsList)
} }
// calcStringCountSum is part of the implementation countSum. // calcStringCountSum is part of the implementation countSum.
@ -9131,12 +9148,17 @@ func (fn *formulaFuncs) STANDARDIZE(argsList *list.List) formulaArg {
return newNumberFormulaArg((x.Number - mean.Number) / stdDev.Number) return newNumberFormulaArg((x.Number - mean.Number) / stdDev.Number)
} }
// stdevp is an implementation of the formula functions STDEVP and STDEV.P. // stdevp is an implementation of the formula functions STDEVP, STDEV.P and
// STDEVPA.
func (fn *formulaFuncs) stdevp(name string, argsList *list.List) formulaArg { func (fn *formulaFuncs) stdevp(name string, argsList *list.List) formulaArg {
if argsList.Len() < 1 { if argsList.Len() < 1 {
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name)) return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
} }
varp := fn.VARP(argsList) fnName := "VARP"
if name == "STDEVPA" {
fnName = "VARPA"
}
varp := fn.vars(fnName, argsList)
if varp.Type != ArgNumber { if varp.Type != ArgNumber {
return varp return varp
} }
@ -9161,6 +9183,15 @@ func (fn *formulaFuncs) STDEVdotP(argsList *list.List) formulaArg {
return fn.stdevp("STDEV.P", argsList) return fn.stdevp("STDEV.P", argsList)
} }
// STDEVPA function calculates the standard deviation of a supplied set of
// values. The syntax of the function is:
//
// STDEVPA(number1,[number2],...)
//
func (fn *formulaFuncs) STDEVPA(argsList *list.List) formulaArg {
return fn.stdevp("STDEVPA", argsList)
}
// getTDist is an implementation for the beta distribution probability density // getTDist is an implementation for the beta distribution probability density
// function. // function.
func getTDist(T, fDF, nType float64) float64 { func getTDist(T, fDF, nType float64) float64 {
@ -9576,6 +9607,9 @@ func (fn *formulaFuncs) vars(name string, argsList *list.List) formulaArg {
} }
for arg := argsList.Front(); arg != nil; arg = arg.Next() { for arg := argsList.Front(); arg != nil; arg = arg.Next() {
for _, token := range arg.Value.(formulaArg).ToList() { for _, token := range arg.Value.(formulaArg).ToList() {
if token.Value() == "" {
continue
}
num := token.ToNumber() num := token.ToNumber()
if token.Value() != "TRUE" && num.Type == ArgNumber { if token.Value() != "TRUE" && num.Type == ArgNumber {
summerA += num.Number * num.Number summerA += num.Number * num.Number

@ -1162,6 +1162,10 @@ func TestCalcCellValue(t *testing.T) {
"=STDEVP(A1:B2,6,-1)": "2.40947204913349", "=STDEVP(A1:B2,6,-1)": "2.40947204913349",
// STDEV.P // STDEV.P
"=STDEV.P(A1:B2,6,-1)": "2.40947204913349", "=STDEV.P(A1:B2,6,-1)": "2.40947204913349",
// STDEVPA
"=STDEVPA(1,3,5,2)": "1.4790199457749",
"=STDEVPA(1,3,5,2,1,0)": "1.63299316185545",
"=STDEVPA(1,3,5,2,TRUE,\"text\")": "1.63299316185545",
// T.DIST // T.DIST
"=T.DIST(1,10,TRUE)": "0.82955343384897", "=T.DIST(1,10,TRUE)": "0.82955343384897",
"=T.DIST(-1,10,TRUE)": "0.17044656615103", "=T.DIST(-1,10,TRUE)": "0.17044656615103",
@ -1190,8 +1194,8 @@ func TestCalcCellValue(t *testing.T) {
"=VAR(1,3,5,0,C1)": "4.91666666666667", "=VAR(1,3,5,0,C1)": "4.91666666666667",
"=VAR(1,3,5,0,C1,TRUE)": "4", "=VAR(1,3,5,0,C1,TRUE)": "4",
// VARA // VARA
"=VARA(1,3,5,0,C1)": "4.7", "=VARA(1,3,5,0,C1)": "4.91666666666667",
"=VARA(1,3,5,0,C1,TRUE)": "3.86666666666667", "=VARA(1,3,5,0,C1,TRUE)": "4",
// VARP // VARP
"=VARP(A1:A5)": "1.25", "=VARP(A1:A5)": "1.25",
"=VARP(1,3,5,0,C1,TRUE)": "3.2", "=VARP(1,3,5,0,C1,TRUE)": "3.2",
@ -1201,8 +1205,8 @@ func TestCalcCellValue(t *testing.T) {
"=VAR.S(1,3,5,0,C1)": "4.91666666666667", "=VAR.S(1,3,5,0,C1)": "4.91666666666667",
"=VAR.S(1,3,5,0,C1,TRUE)": "4", "=VAR.S(1,3,5,0,C1,TRUE)": "4",
// VARPA // VARPA
"=VARPA(1,3,5,0,C1)": "3.76", "=VARPA(1,3,5,0,C1)": "3.6875",
"=VARPA(1,3,5,0,C1,TRUE)": "3.22222222222222", "=VARPA(1,3,5,0,C1,TRUE)": "3.2",
// WEIBULL // WEIBULL
"=WEIBULL(1,3,1,FALSE)": "1.10363832351433", "=WEIBULL(1,3,1,FALSE)": "1.10363832351433",
"=WEIBULL(2,5,1.5,TRUE)": "0.985212776817482", "=WEIBULL(2,5,1.5,TRUE)": "0.985212776817482",
@ -3050,6 +3054,9 @@ func TestCalcCellValue(t *testing.T) {
// STDEV.P // STDEV.P
"=STDEV.P()": "STDEV.P requires at least 1 argument", "=STDEV.P()": "STDEV.P requires at least 1 argument",
"=STDEV.P(\"\")": "#DIV/0!", "=STDEV.P(\"\")": "#DIV/0!",
// STDEVPA
"=STDEVPA()": "STDEVPA requires at least 1 argument",
"=STDEVPA(\"\")": "#DIV/0!",
// T.DIST // T.DIST
"=T.DIST()": "T.DIST requires 3 arguments", "=T.DIST()": "T.DIST requires 3 arguments",
"=T.DIST(\"\",10,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax", "=T.DIST(\"\",10,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
@ -4361,6 +4368,8 @@ func TestCalcCOVAR(t *testing.T) {
"=COVAR(A2:A9,B2:B9)": "16.633125", "=COVAR(A2:A9,B2:B9)": "16.633125",
"=COVARIANCE.P(A1:A9,B1:B9)": "16.633125", "=COVARIANCE.P(A1:A9,B1:B9)": "16.633125",
"=COVARIANCE.P(A2:A9,B2:B9)": "16.633125", "=COVARIANCE.P(A2:A9,B2:B9)": "16.633125",
"=COVARIANCE.S(A1:A9,B1:B9)": "19.0092857142857",
"=COVARIANCE.S(A2:A9,B2:B9)": "19.0092857142857",
} }
for formula, expected := range formulaList { for formula, expected := range formulaList {
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula)) assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula))
@ -4373,6 +4382,8 @@ func TestCalcCOVAR(t *testing.T) {
"=COVAR(A2:A9,B3:B3)": "#N/A", "=COVAR(A2:A9,B3:B3)": "#N/A",
"=COVARIANCE.P()": "COVARIANCE.P requires 2 arguments", "=COVARIANCE.P()": "COVARIANCE.P requires 2 arguments",
"=COVARIANCE.P(A2:A9,B3:B3)": "#N/A", "=COVARIANCE.P(A2:A9,B3:B3)": "#N/A",
"=COVARIANCE.S()": "COVARIANCE.S requires 2 arguments",
"=COVARIANCE.S(A2:A9,B3:B3)": "#N/A",
} }
for formula, expected := range calcError { for formula, expected := range calcError {
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula)) assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula))

Loading…
Cancel
Save