From 1ceccefe7780f52a6df2f0ece2be9655821a1c58 Mon Sep 17 00:00:00 2001 From: Mitchell Skaggs Date: Sat, 16 Jan 2021 09:39:07 -0600 Subject: [PATCH 1/4] Update axios to fix CVE-2020-28168 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0cb50dc167e6e..eda0a52c70ead 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@actions/github": "^4.0.0", "@testing-library/dom": "^7.20.0", "@testing-library/jest-dom": "^5.11.0", - "axios": "^0.19.2", + "axios": "^0.21.1", "axios-mock-adapter": "^1.18.1", "css-to-object": "^1.1.0", "husky": "^4.2.5", From da5b487992d7258391280841ceb9f99e5f96386d Mon Sep 17 00:00:00 2001 From: Mitchell Skaggs Date: Sat, 16 Jan 2021 09:55:03 -0600 Subject: [PATCH 2/4] Use exact normal CDF function for rank calculation Uses Math.js for erf function --- package.json | 3 ++- src/calculateRank.js | 24 +++++++----------------- tests/calculateRank.test.js | 2 +- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index eda0a52c70ead..52dbeea873377 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "emoji-name-map": "^1.2.8", "github-username-regex": "^1.0.0", "prettier": "^2.1.2", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.3", + "mathjs": "^9.0.0" }, "husky": { "hooks": { diff --git a/src/calculateRank.js b/src/calculateRank.js index 76909d09547cd..f821b41bd3da2 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -1,19 +1,9 @@ -// https://stackoverflow.com/a/5263759/10629172 +const { erf } = require("mathjs"); +const sqrt2 = Math.sqrt(2); function normalcdf(mean, sigma, to) { - var z = (to - mean) / Math.sqrt(2 * sigma * sigma); - var t = 1 / (1 + 0.3275911 * Math.abs(z)); - var a1 = 0.254829592; - var a2 = -0.284496736; - var a3 = 1.421413741; - var a4 = -1.453152027; - var a5 = 1.061405429; - var erf = - 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-z * z); - var sign = 1; - if (z < 0) { - sign = -1; - } - return (1 / 2) * (1 + sign * erf); + const z = (to - mean) / (sigma * sqrt2); + const erfZ = erf(z); + return 0.5 + 0.5 * erfZ; } function calculateRank({ @@ -57,8 +47,8 @@ function calculateRank({ issues * ISSUES_OFFSET + stargazers * STARS_OFFSET + prs * PRS_OFFSET + - followers * FOLLOWERS_OFFSET + - totalRepos * REPO_OFFSET + followers * FOLLOWERS_OFFSET + + totalRepos * REPO_OFFSET ) / 100; const normalizedScore = normalcdf(score, TOTAL_VALUES, ALL_OFFSETS) * 100; diff --git a/tests/calculateRank.test.js b/tests/calculateRank.test.js index 4b9fd072b4aa4..7df50b4534999 100644 --- a/tests/calculateRank.test.js +++ b/tests/calculateRank.test.js @@ -13,6 +13,6 @@ describe("Test calculateRank", () => { prs: 300, issues: 200, }), - ).toStrictEqual({ level: "A+", score: 49.16605417270399 }); + ).toStrictEqual({ level: "A+", score: 49.16605835034125 }); }); }); From dacfa85cc4c547b0c755d64157e59b5c5d71be8c Mon Sep 17 00:00:00 2001 From: Mitchell Skaggs Date: Sat, 16 Jan 2021 10:03:42 -0600 Subject: [PATCH 3/4] Document source of normal CDF --- src/calculateRank.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calculateRank.js b/src/calculateRank.js index f821b41bd3da2..e5707b0a26945 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -1,5 +1,6 @@ const { erf } = require("mathjs"); const sqrt2 = Math.sqrt(2); +// https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function function normalcdf(mean, sigma, to) { const z = (to - mean) / (sigma * sqrt2); const erfZ = erf(z); From c36810ad615ee8ddf81b2be6bb65b554251a7c77 Mon Sep 17 00:00:00 2001 From: Mitchell Skaggs Date: Sun, 17 Jan 2021 08:09:13 -0600 Subject: [PATCH 4/4] Clean up implementation based on Wolfram MathWorld directly --- src/calculateRank.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index e5707b0a26945..cf42f9c56b0bb 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -1,10 +1,9 @@ const { erf } = require("mathjs"); -const sqrt2 = Math.sqrt(2); -// https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function +const invSqrt2 = 1 / Math.sqrt(2); +// https://mathworld.wolfram.com/NormalDistribution.html function normalcdf(mean, sigma, to) { - const z = (to - mean) / (sigma * sqrt2); - const erfZ = erf(z); - return 0.5 + 0.5 * erfZ; + const a = (invSqrt2 * (to - mean)) / sigma; + return (1 + erf(a)) / 2; } function calculateRank({