Skip to content

Commit

Permalink
fix(formula): sum,var,std
Browse files Browse the repository at this point in the history
  • Loading branch information
Dushusir committed Jan 30, 2024
1 parent 1174045 commit e20eaa6
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/

/* eslint-disable no-magic-numbers */
import { describe, expect, it } from 'vitest';

import { ArrayValueObject, transformToValueObject, ValueObjectFactory } from '../array-value-object';
Expand Down Expand Up @@ -88,6 +87,54 @@ describe('arrayValueObject test', () => {
});
});

describe('Count', () => {
it('Normal count', () => {
const originValueObject = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, ' ', 1.23, true, false],
[0, '100', '2.34', 'test', -3],
]),
rowCount: 2,
columnCount: 5,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
expect(originValueObject.count()?.getValue()).toBe(6);
});
it('CountA', () => {
const originValueObject = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, ' ', 1.23, true, false],
[0, '100', '2.34', 'test', -3],
]),
rowCount: 2,
columnCount: 5,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
expect(originValueObject.countA()?.getValue()).toBe(10);
});
it('CountBlank', () => {
const originValueObject = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, ' ', 1.23, true, false],
[0, '100', '2.34', 'test', -3],
]),
rowCount: 2,
columnCount: 5,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
expect(originValueObject.countBlank()?.getValue()).toBe(0);
});
});

describe('pick', () => {
it('normal', () => {
const pickArrayValueObject = new ArrayValueObject({
Expand Down Expand Up @@ -144,6 +191,34 @@ describe('arrayValueObject test', () => {
});
});

describe('sum', () => {
it('normal', () => {
expect(originArrayValueObject.sum().getValue()).toStrictEqual(120);
});

// like numpy array
// [
// [1, 0, 1.23, 1, 0],
// [0, 100, 2.34, 0, -3],
// ]
it('nm multiple formats', () => {
const originValueObject = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, ' ', 1.23, true, false],
[0, '100', '2.34', 'test', -3],
]),
rowCount: 2,
columnCount: 5,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});

expect(originValueObject.sum().getValue()).toStrictEqual(101.57);
});
});

describe('mean', () => {
it('normal', () => {
expect(originArrayValueObject.mean().getValue()).toStrictEqual(8);
Expand All @@ -168,7 +243,7 @@ describe('arrayValueObject test', () => {
column: 0,
});

expect(originValueObject.mean().getValue()).toStrictEqual(10.257);
expect(originValueObject.mean().getValue()).toStrictEqual(16.928333333333335);
});
});

Expand All @@ -177,7 +252,7 @@ describe('arrayValueObject test', () => {
expect(originArrayValueObject.var().getValue()).toStrictEqual(18.666666666666668);
});

it('nm multiple formats', () => {
it('var nm multiple formats', () => {
const originValueObject = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, ' ', 1.23, true, false],
Expand All @@ -191,7 +266,7 @@ describe('arrayValueObject test', () => {
column: 0,
});

expect(originValueObject.var().getValue()).toStrictEqual(896.592801);
expect(originValueObject.var().getValue()).toStrictEqual(1382.9296138888888);
});
});

Expand All @@ -214,7 +289,7 @@ describe('arrayValueObject test', () => {
column: 0,
});

expect(originValueObject.std().getValue()).toStrictEqual(29.94315950263098);
expect(originValueObject.std().getValue()).toStrictEqual(37.187761614392564);
});
});

Expand Down Expand Up @@ -299,21 +374,25 @@ describe('arrayValueObject test', () => {
});

it('ValueObjectFactory create StringValueObject ', () => {
const stringValueObject = ValueObjectFactory.create('test');
let stringValueObject = ValueObjectFactory.create('test');

expect(stringValueObject.isString()).toBeTruthy();

stringValueObject = ValueObjectFactory.create(' ');

expect(stringValueObject.isString()).toBeTruthy();
});

it('ValueObjectFactory create ErrorValueObject ', () => {
let errorValueObject = ValueObjectFactory.create(NaN);
let errorValueObject = ValueObjectFactory.create(Number.NaN);

expect(errorValueObject.isError()).toBeTruthy();

errorValueObject = ValueObjectFactory.create(Infinity);
errorValueObject = ValueObjectFactory.create(Number.POSITIVE_INFINITY);

expect(errorValueObject.isError()).toBeTruthy();

errorValueObject = ValueObjectFactory.create(-Infinity);
errorValueObject = ValueObjectFactory.create(Number.NEGATIVE_INFINITY);

expect(errorValueObject.isError()).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,8 @@ export class ArrayValueObject extends BaseValueObject {
override sum() {
let accumulatorAll: BaseValueObject = new NumberValueObject(0);
this.iterator((valueObject) => {
if (valueObject == null) {
// 'test', ' ', blank cell, TRUE and FALSE are ignored
if (valueObject == null || valueObject.isString() || valueObject.isBoolean() || valueObject.isNull()) {
return true; // continue
}

Expand Down Expand Up @@ -801,11 +802,8 @@ export class ArrayValueObject extends BaseValueObject {
override count() {
let accumulatorAll: BaseValueObject = new NumberValueObject(0);
this.iterator((valueObject) => {
if (valueObject == null) {
return true; // continue
}

if (valueObject.isError() || valueObject.isString() || valueObject.isNull()) {
// 'test', ' ', blank cell, TRUE and FALSE are ignored
if (valueObject == null || valueObject.isError() || valueObject.isString() || valueObject.isNull() || valueObject.isBoolean()) {
return true; // continue
}
accumulatorAll = accumulatorAll.plusBy(1) as BaseValueObject;
Expand All @@ -817,11 +815,7 @@ export class ArrayValueObject extends BaseValueObject {
override countA() {
let accumulatorAll: BaseValueObject = new NumberValueObject(0);
this.iterator((valueObject) => {
if (valueObject == null) {
return true; // continue
}

if (valueObject.isNull()) {
if (valueObject == null || valueObject.isNull()) {
return true; // continue
}

Expand All @@ -834,7 +828,7 @@ export class ArrayValueObject extends BaseValueObject {
override countBlank() {
let accumulatorAll: BaseValueObject = new NumberValueObject(0);
this.iterator((valueObject) => {
if (valueObject != null) {
if (valueObject != null && !valueObject.isNull()) {
return true; // continue
}

Expand Down Expand Up @@ -1066,8 +1060,8 @@ export class ArrayValueObject extends BaseValueObject {
override mean(): BaseValueObject {
const sum = this.sum();

// Count strings in
const count = this.countA();
// Like sum, ignore strings and booleans
const count = this.count();

return sum.divided(count);
}
Expand Down Expand Up @@ -1095,35 +1089,39 @@ export class ArrayValueObject extends BaseValueObject {
return allValue.get(0, (count - 1) / 2);
}

// TODO ddof, ignore strings and booleans
override var(): BaseValueObject {
const mean = this.mean();

// let isError = null;
const squaredDifferences: BaseValueObject[][] = [];
this.iterator((valueObject: Nullable<BaseValueObject>, row: number, column: number) => {
if (valueObject == null || valueObject.isError() || valueObject.isString()) {
valueObject = new NumberValueObject(0);
const squaredDifferences: BaseValueObject[][] = [[]];
this.iterator((valueObject: Nullable<BaseValueObject>) => {
// for VARPA and VARA, strings and FALSE are counted as 0, TRUE is counted as 1
// for VAR.S/VAR, or VAR.P/VARP, strings,TRUE and FALSE are ignored
// Since sum ignores strings and booleans, they are ignored here too, and VAR.S and VAR.P are used more

// VAR.S assumes that its arguments are a sample of the population, like numpy.var(data, ddof=1)
// VAR.P assumes that its arguments are the entire population, like numpy.var(data, ddof=0)
// numpy.var uses ddof=0 by default, so we use ddof=0 here
if (valueObject == null || valueObject.isError() || valueObject.isString() || valueObject.isBoolean() || valueObject.isNull()) {
return;
}

let baseValueObject = valueObject.minus(mean).pow(new NumberValueObject(2, true));
const baseValueObject = valueObject.minus(mean).pow(new NumberValueObject(2, true));

if (baseValueObject.isError()) {
baseValueObject = new NumberValueObject(0);
}

if (squaredDifferences[row] == null) {
squaredDifferences[row] = [];
return;
}

squaredDifferences[row][column] = baseValueObject;
squaredDifferences[0].push(baseValueObject);
});

const { _rowCount, _columnCount, _unitId, _sheetId, _currentRow, _currentColumn } = this;

const squaredDifferencesArrayObject = new ArrayValueObject({
calculateValueList: squaredDifferences,
rowCount: _rowCount,
columnCount: _columnCount,
rowCount: 1,
columnCount: squaredDifferences[0].length,
unitId: _unitId,
sheetId: _sheetId,
row: _currentRow,
Expand All @@ -1133,6 +1131,14 @@ export class ArrayValueObject extends BaseValueObject {
return squaredDifferencesArrayObject.mean();
}

/**
* STDEV.P: ddof=0, ignore strings and booleans
* STDEV.S: ddof=1, ignore strings and booleans
*
* STDEVPA: ddof=0,
* STDEVA: ddof=1,
* @returns
*/
override std(): BaseValueObject {
const variance = this.var();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,11 @@ export class BooleanValueObject extends BaseValueObject {
}

override sqrt(): BaseValueObject {
return this._convertTonNumber();
return this._convertTonNumber().sqrt();
}

override cbrt(): BaseValueObject {
return this._convertTonNumber();
return this._convertTonNumber().cbrt();
}

override cos(): BaseValueObject {
Expand Down

0 comments on commit e20eaa6

Please sign in to comment.