Auto grading

USTC 自动评价 tqm.ustc.edu.cn

目前为 2023-04-13 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Auto grading
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.1
  5. // @description USTC 自动评价 tqm.ustc.edu.cn
  6. // @author PRO_2684
  7. // @match https://tqm.ustc.edu.cn/index.html*
  8. // @icon https://tqm.ustc.edu.cn/favicon.ico
  9. // @grant none
  10. // @license unlicense
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. let standard_answers = {
  16. '教学内容': ['非常同意'],
  17. '教学资源': ['非常满意', '非常同意'],
  18. '教材单列': ['非常满意'],
  19. '课程难度': ['适合'],
  20. '教学态度': ['非常同意'],
  21. '教学水平': ['非常同意'],
  22. '教学手段': ['非常同意'],
  23. '教学方法': ['非常同意'],
  24. '师生互动': ['非常同意'],
  25. '学习投入': ['3-4小时'],
  26. '知识掌握': ['非常同意'],
  27. '能力提升': ['非常同意'],
  28. '兴趣培养': ['非常同意'],
  29. '推荐度': ['会'],
  30. '整体评价': ['非常好'],
  31. '课程准备': ['非常同意'],
  32. '实验报告': ['非常同意'],
  33. '教学表达': ['非常同意'],
  34. '课程安排': ['非常同意'],
  35. '课程考核': ['非常同意'],
  36. '纪律约束': ['非常同意'],
  37. '教师示范': ['非常同意'],
  38. '课程氛围': ['非常同意'],
  39. '素养提升': ['非常同意'],
  40. '个人发展': ['非常同意'],
  41. '1.该助教是否随堂听课?': ['全部'],
  42. '2.该助教批改作业是否认真?': ['非常认真'],
  43. '3.该助教习题课/答疑课准备是否充分?': ['非常充分'],
  44. '4.该助教对课程知识的掌握是否扎实?': ['非常扎实'],
  45. '5.该助教习题课/答疑课互动中表达是否清晰?': ['非常清晰'],
  46. '6.该助教的综合表现': ['优秀'],
  47. '1.该助教实验课前准备是否充分?': ['非常充分'],
  48. '3.该助教实验过程指导是否认真?': ['非常认真'],
  49. '4.该助教批改实验报告是否认真?': ['非常认真'],
  50. '5.该助教对课程知识的掌握是否扎实?': ['非常扎实'],
  51. '6.该助教答疑/讨论中表达是否清晰?': ['非常清晰'],
  52. '7.该助教的综合表现': ['优秀'],
  53. '1.您对本课程的总体评价': ['非常好'],
  54. '2.您认为本课程的难度': ['适中'],
  55. '3.您认为本课程的内容': ['适中'],
  56. '4.您认为本课程的进度': ['适中'],
  57. '5.您认为本课程的教材(或讲义)': ['非常好'],
  58. '6.本课程的上课形式(如有极其少量板书列为“纯PPT”,不列为“PPT为主,板书为辅”,体育课请勾选“以上都不是”)': ['板书为主,PPT为辅'],
  59. '7.您对教师的总体评价': ['非常好'],
  60. '11.您在这门课上平均每周花费约多少课外时间?': ['3-4小时'],
  61. '': [''],
  62. '': [''],
  63. };
  64. let menu_root;
  65. function append_link() {
  66. let auto_grade = document.createElement('li');
  67. auto_grade.innerText = "自动评价";
  68. auto_grade.onclick = grade;
  69. auto_grade.setAttribute('class', 'ant-menu-item');
  70. menu_root.appendChild(auto_grade);
  71. let ignore_continue = document.createElement('li');
  72. ignore_continue.innerText = "忽略并转到下一个";
  73. ignore_continue.onclick = ignore;
  74. ignore_continue.setAttribute('class', 'ant-menu-item');
  75. menu_root.appendChild(ignore_continue);
  76. }
  77. function grade() {
  78. let questions = document.querySelectorAll("[class|='index_subject']");
  79. questions.forEach((question) => {
  80. let required = Boolean(question.querySelector('[class|="index_necessary"]'));
  81. if (!required) return;
  82. let tmp = question.querySelector("[class|='index_title']").querySelectorAll('p');
  83. let title = tmp[tmp.length - 1].innerText;
  84. let standard_answer = standard_answers[title];
  85. console.log(`[Auto grading] ${title}: ${standard_answer}`);
  86. if (standard_answer) {
  87. let options = question.querySelectorAll('[style="width: 100%;"]');
  88. options.forEach((option) => {
  89. let is_standard_answer = (standard_answer.indexOf(option.innerText) >= 0);
  90. if (is_standard_answer) {
  91. option.firstChild.click();
  92. }
  93. });
  94. }
  95. });
  96. }
  97. function ignore() {
  98. let ignore_btn = root_node.querySelector("[class|='TaskDetailsMainContent_normalButton']");
  99. if (ignore_btn && ignore_btn.parentElement.parentElement.parentElement.getAttribute('aria-hidden') == 'false') {
  100. ignore_btn.click();
  101. } else {
  102. console.log("[Auto grading] 未找到忽略按钮!");
  103. }
  104. let tabs = root_node.querySelector("[class='ant-tabs-nav-scroll']");
  105. if (tabs) {
  106. tabs = tabs.children[0].children[0];
  107. } else {
  108. console.log("[Auto grading] 未找到教师/助教列表!");
  109. return;
  110. }
  111. let flag = false;
  112. let tab;
  113. for (tab of tabs.children) {
  114. if (flag) {
  115. tab.click();
  116. break;
  117. } else if (tab.getAttribute('aria-selected') == 'true') {
  118. flag = true;
  119. }
  120. }
  121. }
  122. const root_node = document.getElementById('root');
  123. const config = { attributes: false, childList: true, subtree: true };
  124. const callback = function(mutations, observer) {
  125. menu_root = root_node.querySelector('.ant-menu-root');
  126. if (menu_root) {
  127. append_link();
  128. observer.disconnect();
  129. }
  130. }
  131. const observer = new MutationObserver(callback);
  132. observer.observe(root_node, config);
  133. })();