c.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * Calculates the exponential cdf.
  3. *
  4. * @param {number} x The value.
  5. * @returns {number} The exponential cdf.
  6. */
  7. function exponential_cdf(x) {
  8. return 1 - 2 ** -x;
  9. }
  10. /**
  11. * Calculates the log normal cdf.
  12. *
  13. * @param {number} x The value.
  14. * @returns {number} The log normal cdf.
  15. */
  16. function log_normal_cdf(x) {
  17. // approximation
  18. return x / (1 + x);
  19. }
  20. /**
  21. * Calculates the users rank.
  22. *
  23. * @param {object} params Parameters on which the user's rank depends.
  24. * @param {boolean} params.all_commits Whether `include_all_commits` was used.
  25. * @param {number} params.commits Number of commits.
  26. * @param {number} params.prs The number of pull requests.
  27. * @param {number} params.issues The number of issues.
  28. * @param {number} params.reviews The number of reviews.
  29. * @param {number} params.repos Total number of repos.
  30. * @param {number} params.stars The number of stars.
  31. * @param {number} params.followers The number of followers.
  32. * @returns {{level: string, percentile: number}}} The users rank.
  33. */
  34. function calculateRank({
  35. all_commits,
  36. commits,
  37. prs,
  38. issues,
  39. reviews,
  40. // eslint-disable-next-line no-unused-vars
  41. repos, // unused
  42. stars,
  43. followers,
  44. }) {
  45. const COMMITS_MEDIAN = all_commits ? 1000 : 250,
  46. COMMITS_WEIGHT = 2;
  47. const PRS_MEDIAN = 50,
  48. PRS_WEIGHT = 3;
  49. const ISSUES_MEDIAN = 25,
  50. ISSUES_WEIGHT = 1;
  51. const REVIEWS_MEDIAN = 2,
  52. REVIEWS_WEIGHT = 1;
  53. const STARS_MEDIAN = 50,
  54. STARS_WEIGHT = 4;
  55. const FOLLOWERS_MEDIAN = 10,
  56. FOLLOWERS_WEIGHT = 1;
  57. const TOTAL_WEIGHT =
  58. COMMITS_WEIGHT +
  59. PRS_WEIGHT +
  60. ISSUES_WEIGHT +
  61. REVIEWS_WEIGHT +
  62. STARS_WEIGHT +
  63. FOLLOWERS_WEIGHT;
  64. const THRESHOLDS = [1, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100];
  65. const LEVELS = ["S", "A+", "A", "A-", "B+", "B", "B-", "C+", "C"];
  66. const rank =
  67. 1 -
  68. (COMMITS_WEIGHT * exponential_cdf(commits / COMMITS_MEDIAN) +
  69. PRS_WEIGHT * exponential_cdf(prs / PRS_MEDIAN) +
  70. ISSUES_WEIGHT * exponential_cdf(issues / ISSUES_MEDIAN) +
  71. REVIEWS_WEIGHT * exponential_cdf(reviews / REVIEWS_MEDIAN) +
  72. STARS_WEIGHT * log_normal_cdf(stars / STARS_MEDIAN) +
  73. FOLLOWERS_WEIGHT * log_normal_cdf(followers / FOLLOWERS_MEDIAN)) /
  74. TOTAL_WEIGHT;
  75. const level = LEVELS[THRESHOLDS.findIndex((t) => rank * 100 <= t)];
  76. return { level, percentile: rank * 100 };
  77. }
  78. module.exports = { calculateRank };
  79. // export default calculateRank;