This closes #809, and add new fn: HARMEAN

This commit is contained in:
xuri 2021-03-25 00:05:02 +08:00
parent ab2c1c8fe1
commit e1abdb0e5a
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
4 changed files with 46 additions and 4 deletions

35
calc.go
View File

@ -282,6 +282,7 @@ var tokenPriority = map[string]int{
// GAMMA // GAMMA
// GAMMALN // GAMMALN
// GCD // GCD
// HARMEAN
// HEX2BIN // HEX2BIN
// HEX2DEC // HEX2DEC
// HEX2OCT // HEX2OCT
@ -3927,6 +3928,40 @@ func (fn *formulaFuncs) GAMMALN(argsList *list.List) formulaArg {
return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument") return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
} }
// HARMEAN function calculates the harmonic mean of a supplied set of values.
// The syntax of the function is:
//
// HARMEAN(number1,[number2],...)
//
func (fn *formulaFuncs) HARMEAN(argsList *list.List) formulaArg {
if argsList.Len() < 1 {
return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument")
}
if min := fn.MIN(argsList); min.Number < 0 {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
}
number, val, cnt := 0.0, 0.0, 0.0
for token := argsList.Front(); token != nil; token = token.Next() {
arg := token.Value.(formulaArg)
switch arg.Type {
case ArgString:
num := arg.ToNumber()
if num.Type != ArgNumber {
continue
}
number = num.Number
case ArgNumber:
number = arg.Number
}
if number <= 0 {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
}
val += (1 / number)
cnt++
}
return newNumberFormulaArg(1 / (val / cnt))
}
// KURT function calculates the kurtosis of a supplied set of values. The // KURT function calculates the kurtosis of a supplied set of values. The
// syntax of the function is: // syntax of the function is:
// //

View File

@ -605,6 +605,9 @@ func TestCalcCellValue(t *testing.T) {
// GAMMALN // GAMMALN
"=GAMMALN(4.5)": "2.453736570842443", "=GAMMALN(4.5)": "2.453736570842443",
"=GAMMALN(INT(1))": "0", "=GAMMALN(INT(1))": "0",
// HARMEAN
"=HARMEAN(2.5,3,0.5,1,3)": "1.229508196721312",
"=HARMEAN(\"2.5\",3,0.5,1,INT(3),\"\")": "1.229508196721312",
// KURT // KURT
"=KURT(F1:F9)": "-1.033503502551368", "=KURT(F1:F9)": "-1.033503502551368",
"=KURT(F1,F2:F9)": "-1.033503502551368", "=KURT(F1,F2:F9)": "-1.033503502551368",
@ -1393,6 +1396,10 @@ func TestCalcCellValue(t *testing.T) {
"=GAMMALN(F1)": "GAMMALN requires 1 numeric argument", "=GAMMALN(F1)": "GAMMALN requires 1 numeric argument",
"=GAMMALN(0)": "#N/A", "=GAMMALN(0)": "#N/A",
"=GAMMALN(INT(0))": "#N/A", "=GAMMALN(INT(0))": "#N/A",
// HARMEAN
"=HARMEAN()": "HARMEAN requires at least 1 argument",
"=HARMEAN(-1)": "#N/A",
"=HARMEAN(0)": "#N/A",
// KURT // KURT
"=KURT()": "KURT requires at least 1 argument", "=KURT()": "KURT requires at least 1 argument",
"=KURT(F1,INT(1))": "#DIV/0!", "=KURT(F1,INT(1))": "#DIV/0!",

View File

@ -2472,8 +2472,8 @@ func newAlignment(style *Style) *xlsxAlignment {
func newProtection(style *Style) *xlsxProtection { func newProtection(style *Style) *xlsxProtection {
var protection xlsxProtection var protection xlsxProtection
if style.Protection != nil { if style.Protection != nil {
protection.Hidden = style.Protection.Hidden protection.Hidden = &style.Protection.Hidden
protection.Locked = style.Protection.Locked protection.Locked = &style.Protection.Locked
} }
return &protection return &protection
} }

View File

@ -49,8 +49,8 @@ type xlsxAlignment struct {
// set. The cell protection properties do not take effect unless the sheet has // set. The cell protection properties do not take effect unless the sheet has
// been protected. // been protected.
type xlsxProtection struct { type xlsxProtection struct {
Hidden bool `xml:"hidden,attr"` Hidden *bool `xml:"hidden,attr"`
Locked bool `xml:"locked,attr"` Locked *bool `xml:"locked,attr"`
} }
// xlsxLine expresses a single set of cell border. // xlsxLine expresses a single set of cell border.