AtutorSolver

Helps to solve tests with ChatGPT

  1. // ==UserScript==
  2. // @name AtutorSolver
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description Helps to solve tests with ChatGPT
  6. // @author Propsi4
  7. // @include https://dl.tntu.edu.ua/mods/_standard/tests/*.php?*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=dl.tntu.edu.ua
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13.  
  14. let hide = false
  15.  
  16. const hide_divs = (hide, divs) => {
  17. if(hide){
  18. divs.forEach(div => {
  19. Array.from(div.children).forEach((child) => {
  20. if(child.id === "prompt-area"){
  21. child.style.display = "none"
  22. }
  23. })
  24. })
  25. }else{
  26. divs.forEach(div => {
  27. Array.from(div.children).forEach((child) => {
  28. if(child.id === "prompt-area"){
  29. child.style.display = "block"
  30. }
  31. })
  32. })
  33. }
  34. }
  35.  
  36. (function() {
  37. 'use strict';
  38.  
  39. const row_divs = document.getElementsByClassName("row")
  40. const page_wrap = document.getElementsByClassName("page-wrap")[0]
  41. const hide_button = document.createElement("button")
  42. hide_button.innerText = "X"
  43. hide_button.style.position = "fixed"
  44. hide_button.style.top = "0"
  45. hide_button.style.right = "0"
  46. hide_button.style.zIndex = "1000"
  47. hide_button.style.opacity = "20%"
  48. let hide = false
  49.  
  50. page_wrap.appendChild(hide_button)
  51. // get only divs with children p and ul.multichoice-question
  52. const question_divs = Array.from(row_divs).filter(row_div => {
  53. const children = Array.from(row_div.children)
  54. const has_p = children.some(child => child.tagName === "P")
  55. const has_ul = children.some(child => child.tagName === "UL" && (child.classList.contains("multichoice-question") || child.classList.contains("multianswer-question")))
  56. return has_p && has_ul
  57. })
  58.  
  59. hide_button.onclick = () => {
  60. hide = !hide
  61. hide_divs(hide, question_divs)
  62. }
  63. document.addEventListener('keydown', function(event) {
  64. if (event.shiftKey && event.key === 'Z') {
  65. hide = !hide
  66. hide_divs(hide, question_divs)
  67. }
  68. });
  69.  
  70. document.addEventListener('mousedown', function(event) {
  71. if (event.button === 1) {
  72. hide = !hide
  73. hide_divs(hide, question_divs)
  74. }
  75. });
  76.  
  77. const question_data = question_divs.map(question_div => {
  78. const question_text = question_div.children[0].innerText
  79. // if question ul class is multichoice-question, then it is multichoice question
  80. // get ul tag
  81. const ul_div = Array.from(question_div.children).find(child => child.tagName === "UL")
  82. const type = ul_div.classList[0]
  83. // ignore last answer, because it is "I don't know"
  84. if(type == "multichoice-question"){
  85. const answers = Array.from(ul_div.children).slice(0, -1).map(answer_div => {
  86. // try to get answer input, if error then skip
  87. try{
  88. const answer_input = answer_div.children[0]
  89. const answer_text = answer_div.children[1].innerText
  90. return {
  91. answer_text,
  92. answer_input
  93. }
  94. } catch (error) {
  95. return null
  96. }})
  97. return {
  98. question_div,
  99. question_text,
  100. type,
  101. answers
  102. }
  103. }else{
  104. const answers = Array.from(ul_div.children).map(answer_div => {
  105. // try to get answer input, if error then skip
  106. try{
  107. const answer_input = answer_div.children[0]
  108. const answer_text = answer_div.children[1].innerText
  109. return {
  110. answer_text,
  111. question_div,
  112. answer_input
  113. }
  114. } catch (error) {
  115. return null
  116. }})
  117. return {
  118. question_div,
  119. question_text,
  120. type,
  121. answers
  122. }
  123. }
  124. })
  125.  
  126. // add a textarea to every question_div
  127. question_divs.forEach((question_div, question_index) => {
  128. const textarea = document.createElement("textarea")
  129. const {question_text, type, answers} = question_data[question_index]
  130. let prompt = `Кількість правильних відповідей: ${type == "multichoice-question" ? "Одна правильна відповідь" : "Декілька правильних відповідей"}
  131. Запитання: ${question_text}\n${answers.map((answer, index) =>
  132. `Відповідь ${index + 1}: ${answer?.answer_text}`).join("\n")}`
  133.  
  134. textarea.id = "prompt-area"
  135. textarea.style.width = "100%"
  136. textarea.style.height = "100px"
  137. textarea.style.resize = "none"
  138. textarea.value = prompt
  139.  
  140.  
  141. question_div.appendChild(textarea)
  142. })
  143.  
  144.  
  145. })();