From 2658a8737d3cadc7d2e03c3777ed683c73d817cb Mon Sep 17 00:00:00 2001 From: anuraghazra Date: Tue, 14 Jul 2020 14:08:57 +0530 Subject: [PATCH] improve: improved rating algorithm wip --- src/calculateRank.js | 79 ++++++++++++++++++++++++++++--------- tests/calculateRank.test.js | 2 +- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index 9aeeae20..76909d09 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -1,3 +1,21 @@ +// https://stackoverflow.com/a/5263759/10629172 +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); +} + function calculateRank({ totalRepos, totalCommits, @@ -13,12 +31,24 @@ function calculateRank({ const STARS_OFFSET = 0.75; const PRS_OFFSET = 0.5; const FOLLOWERS_OFFSET = 0.45; + const REPO_OFFSET = 1; - const FIRST_STEP = 0; - const SECOND_STEP = 5; - const THIRD_STEP = 20; - const FOURTH_STEP = 50; - const FIFTH_STEP = 130; + const ALL_OFFSETS = + CONTRIBS_OFFSET + + ISSUES_OFFSET + + STARS_OFFSET + + PRS_OFFSET + + FOLLOWERS_OFFSET + + REPO_OFFSET; + + const RANK_S_VALUE = 1; + const RANK_DOUBLE_A_VALUE = 25; + const RANK_A2_VALUE = 45; + const RANK_A3_VALUE = 60; + const RANK_B_VALUE = 100; + + const TOTAL_VALUES = + RANK_S_VALUE + RANK_A2_VALUE + RANK_A3_VALUE + RANK_B_VALUE; // prettier-ignore const score = ( @@ -27,26 +57,37 @@ function calculateRank({ issues * ISSUES_OFFSET + stargazers * STARS_OFFSET + prs * PRS_OFFSET + - followers * FOLLOWERS_OFFSET - ) / totalRepos; + followers * FOLLOWERS_OFFSET + + totalRepos * REPO_OFFSET + ) / 100; + + const normalizedScore = normalcdf(score, TOTAL_VALUES, ALL_OFFSETS) * 100; let level = ""; - if (score == FIRST_STEP) { - level = "B"; - } else if (score > FIRST_STEP && score <= SECOND_STEP) { - level = "B+"; - } else if (score > SECOND_STEP && score <= THIRD_STEP) { - level = "A"; - } else if (score > THIRD_STEP && score <= FOURTH_STEP) { - level = "A+"; - } else if (score > FOURTH_STEP && score <= FIFTH_STEP) { - level = "A++"; - } else if (score > FIFTH_STEP) { + if (normalizedScore < RANK_S_VALUE) { level = "S+"; } + if ( + normalizedScore >= RANK_S_VALUE && + normalizedScore < RANK_DOUBLE_A_VALUE + ) { + level = "S"; + } + if ( + normalizedScore >= RANK_DOUBLE_A_VALUE && + normalizedScore < RANK_A2_VALUE + ) { + level = "A++"; + } + if (normalizedScore >= RANK_A2_VALUE && normalizedScore < RANK_A3_VALUE) { + level = "A+"; + } + if (normalizedScore >= RANK_A3_VALUE && normalizedScore < RANK_B_VALUE) { + level = "B+"; + } - return { level, score }; + return { level, score: normalizedScore }; } module.exports = calculateRank; diff --git a/tests/calculateRank.test.js b/tests/calculateRank.test.js index 861f66b3..52bb3689 100644 --- a/tests/calculateRank.test.js +++ b/tests/calculateRank.test.js @@ -13,6 +13,6 @@ describe("Test calculateRank", () => { prs: 300, issues: 200, }) - ).toStrictEqual({ level: "S+", score: 192.13 }); + ).toStrictEqual({ level: "A+", score: 49.16605417270399 }); }); });