ST_FUNC開発日記

建築構造設計Excelアドイン開発の記録

配列を使った断面性能関数のテストの共通化

前回記事で配列のテストを行ったが、各断面形状ごとに3パターンずつ書くのは面倒だし、寸法も3か所に書くのはミスの元なので、共通化を試みる。

各テストを別関数にくくって、断面性能の計算部分をデリゲート的に渡してあげればいいはず。

typescriptのデリゲートはよくわからないけどこの辺を見ればいいのかな?

検証内容を外出しにした結果がこちら。

function verifySecProperty(
  testCases: [string, number, number][],
  secPropertyFunction: (propertyTypes: string[][]) => number[][]
) {
  testCases.forEach(([input, expected, numDigits]) => {
    expect(secPropertyFunction([[input]])[0][0]).toBeCloseTo(expected, numDigits);
  });

  const parameterTypesV = testCases.map(([input]) => [input]);
  const resultsV = secPropertyFunction(parameterTypesV);
  testCases.forEach(([input, expected, numDigits], i) => {
    expect(resultsV[i][0]).toBeCloseTo(expected, numDigits);
  });

  const parameterTypesH = [testCases.map(([input]) => input)];
  const resultsH = secPropertyFunction(parameterTypesH);
  testCases.forEach(([input, expected, numDigits], i) => {
    expect(resultsH[0][i]).toBeCloseTo(expected, numDigits);
  });
}

test("SecBuildBox", () => {
  const testCases: [string, number, number][] = [
    ["A", 76100.0, 9],
    ["ZY", 24446708.3333333, 7],
    ["ZZ", 19098293.4166667, 7],
    ["m", 597.385, 12],
    ["iY", 400.777073164208, 12],
    ["iZ", 316.836310923171, 12],
    ["IY", 12223354166.6667, 4],
    ["IZ", 7639317366.66666, 4],
  ];
  verifySecProperty(testCases, (propertyTypes: string[][]) => secBuildBox(propertyTypes, 1000, 800, 19, 25));
});

BuildBoxだけだと長さはあまり変わらないけど、他の断面もやるときに威力を発揮するはず。

そして、いまさらながら、numDigitsをいちいち指定するのが面倒になってきた。

以前に決めた下式をそのままコードで書いてしまおう。

小数点以下の桁数=-\mathrm{ROUNDUP}(\log_{10}(数値))+13

テストの比較部分を自動化するのはちょっと危険な気もするけど、手間削減のために妥協。

結果が下記。

function numDigits(expected: number): number {
  return -Math.ceil(Math.log10(expected)) + 13;
}

function verifySecProperty(
  testCases: [string, number][],
  secPropertyFunction: (propertyTypes: string[][]) => number[][]
) {
  testCases.forEach(([input, expected]) => {
    expect(secPropertyFunction([[input]])[0][0]).toBeCloseTo(expected, numDigits(expected));
  });

  const parameterTypesV = testCases.map(([input]) => [input]);
  const resultsV = secPropertyFunction(parameterTypesV);
  testCases.forEach(([input, expected], i) => {
    expect(resultsV[i][0]).toBeCloseTo(expected, numDigits(expected));
  });

  const parameterTypesH = [testCases.map(([input]) => input)];
  const resultsH = secPropertyFunction(parameterTypesH);
  testCases.forEach(([input, expected], i) => {
    expect(resultsH[0][i]).toBeCloseTo(expected, numDigits(expected));
  });
}

test("SecBuildBox", () => {
  const testCases: [string, number][] = [
    ["A", 76100.0],
    ["ZY", 24446708.3333333],
    ["ZZ", 19098293.4166667],
    ["m", 597.385],
    ["iY", 400.777073164208],
    ["iZ", 316.836310923171],
    ["IY", 12223354166.6667],
    ["IZ", 7639317366.66666],
  ];
  verifySecProperty(testCases, (propertyTypes: string[][]) => secBuildBox(propertyTypes, 1000, 800, 19, 25));
});

これで、断面性能関数を増やした時の実装はだいぶ楽になったかな。

secBuildBox関数のテストの実装部分の共通化とnumDigits算出の自動化 · st-func/st_func_addin@ae106de · GitHub