Calculate Average Score

Данный скрипт позволяет считать средний балл в БРС и также менять баллы чтоб посчитать приблизительно какой может быть ваш средний балл

  1. // ==UserScript==
  2. // @name Calculate Average Score
  3. // @namespace https://gist.github.com/ve3xone/93ee59086618b9e3925bc4376f0feec0
  4. // @version 2025-01-17-v1.02
  5. // @description Данный скрипт позволяет считать средний балл в БРС и также менять баллы чтоб посчитать приблизительно какой может быть ваш средний балл
  6. // @author Vladislav Startsev (aka ve3xone)
  7. // @match https://istudent.urfu.ru/s/servis-informirovaniya-studenta-o-ballah-brs*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=urfu.ru
  9. // @grant none
  10. // @license GNU-GPLV3
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. const originalScores = new Map();
  17. let includeHidden = false;
  18.  
  19. // Make scores editable
  20. function makeScoresEditable() {
  21. const disciplineContainer = document.querySelector("#disciplines");
  22. if (!disciplineContainer) {
  23. console.log("No disciplines found.");
  24. return;
  25. }
  26.  
  27. const disciplineElements = disciplineContainer.querySelectorAll(".rating-discipline-outer-container");
  28.  
  29. disciplineElements.forEach((element) => {
  30. const scoreElement = element.querySelector(".td-1");
  31. const disciplineId = element.querySelector(".rating-discipline")?.getAttribute("data-discipline-id");
  32.  
  33. if (scoreElement && disciplineId) {
  34. const scoreText = scoreElement.textContent.trim();
  35.  
  36. // Load saved score if available
  37. const savedScore = localStorage.getItem(`score_${disciplineId}`);
  38. if (savedScore) {
  39. scoreElement.textContent = savedScore;
  40. scoreElement.style.color = "blue";
  41. }
  42.  
  43. // Save the original score
  44. if (!originalScores.has(scoreElement)) {
  45. originalScores.set(scoreElement, scoreText);
  46. }
  47.  
  48. // Make the score editable
  49. scoreElement.contentEditable = true;
  50. scoreElement.style.border = "1px dashed #000";
  51. scoreElement.style.backgroundColor = "#f9f9f9";
  52. scoreElement.addEventListener("input", () => {
  53. scoreElement.style.color = "blue"; // Highlight changed scores
  54. localStorage.setItem(`score_${disciplineId}`, scoreElement.textContent.trim()); // Save score locally with discipline ID
  55. updateAverageScore(); // Recalculate average on change
  56. });
  57. }
  58. });
  59. }
  60.  
  61. // Calculate the average score
  62. function calculateAverage() {
  63. const disciplineContainer = document.querySelector("#disciplines");
  64. if (!disciplineContainer) {
  65. console.log("No disciplines found.");
  66. return 0;
  67. }
  68.  
  69. const disciplineElements = disciplineContainer.querySelectorAll(includeHidden
  70. ? ".rating-discipline-outer-container"
  71. : ".rating-discipline-outer-container:not(.hidden)");
  72.  
  73. let totalScore = 0;
  74. let count = 0;
  75.  
  76. disciplineElements.forEach((element) => {
  77. const scoreElement = element.querySelector(".td-1");
  78. if (scoreElement) {
  79. const scoreText = scoreElement.textContent.trim();
  80. const score = parseFloat(scoreText);
  81.  
  82. // Include only valid numerical scores
  83. // && score > 0
  84. if (!isNaN(score) ) {
  85. totalScore += score;
  86. count++;
  87. }
  88. }
  89. });
  90.  
  91. return count > 0 ? totalScore / count : 0;
  92. }
  93.  
  94. // Update the average score display
  95. function updateAverageScore() {
  96. const averageScore = calculateAverage();
  97. const professionElement = document.querySelector(".education-service-info");
  98.  
  99. if (professionElement) {
  100. let averageDisplay = professionElement.querySelector(".average-score-display");
  101.  
  102. if (!averageDisplay) {
  103. averageDisplay = document.createElement("span");
  104. averageDisplay.className = "average-score-display";
  105. averageDisplay.style.marginLeft = "10px";
  106. averageDisplay.style.fontWeight = "bold";
  107. professionElement.appendChild(averageDisplay);
  108. }
  109.  
  110. averageDisplay.textContent = `Средний балл: ${averageScore.toFixed(2)}`;
  111. }
  112. }
  113.  
  114. // Toggle hidden disciplines
  115. function toggleHiddenDisciplines() {
  116. includeHidden = !includeHidden;
  117. updateAverageScore();
  118. }
  119.  
  120. // Reset scores to their original values
  121. function resetScores() {
  122. originalScores.forEach((originalValue, element) => {
  123. element.textContent = originalValue;
  124. element.style.color = ""; // Remove highlight
  125. });
  126.  
  127. // Clear local storage
  128. localStorage.clear();
  129.  
  130. updateAverageScore();
  131.  
  132. console.log("Сброс выполнен.");
  133. alert("Все изменения сброшены.");
  134. }
  135.  
  136. // Add controls to the page
  137. function addControls() {
  138. const professionElement = document.querySelector(".education-service-info");
  139.  
  140. if (professionElement) {
  141. const toggleCheckbox = document.createElement("input");
  142. toggleCheckbox.type = "checkbox";
  143. toggleCheckbox.style.marginLeft = "10px";
  144. toggleCheckbox.addEventListener("change", toggleHiddenDisciplines);
  145.  
  146. const label = document.createElement("label");
  147. label.textContent = "Включать скрытые дисциплины";
  148. label.style.marginLeft = "5px";
  149. label.style.fontSize = "14px";
  150. label.appendChild(toggleCheckbox);
  151.  
  152. professionElement.appendChild(label);
  153. }
  154.  
  155. const resetButton = document.createElement("button");
  156. resetButton.textContent = "Сбросить изменения";
  157. resetButton.style = buttonStyle();
  158. resetButton.style.bottom = "10px";
  159. resetButton.addEventListener("click", resetScores);
  160. document.body.appendChild(resetButton);
  161. }
  162.  
  163. // Button style function
  164. function buttonStyle() {
  165. return `
  166. position: fixed;
  167. right: 10px;
  168. padding: 10px 20px;
  169. background-color: #007bff;
  170. color: #fff;
  171. border: none;
  172. border-radius: 5px;
  173. cursor: pointer;
  174. z-index: 1000;
  175. `;
  176. }
  177.  
  178. // Initialize the script
  179. function init() {
  180. makeScoresEditable();
  181. addControls();
  182. updateAverageScore(); // Update average score on page load
  183. }
  184.  
  185. init();
  186. })();