iassignHelpers.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // iVProg - www.usp.br/line/ivprog
  2. // LInE - Free Education, Private Data
  3. import { setTestCases, getTestCases } from "../visualUI/functions";
  4. import { generate } from "../visualUI/code_generator";
  5. import { IVProgAssessment } from "../assessment/ivprogAssessment";
  6. import { TestConsole } from "./testConsole";
  7. import { parseLogs } from "./../services/userLog";
  8. import { SemanticAnalyser } from "../processor/semantic/semanticAnalyser";
  9. import { Maybe } from "./maybe";
  10. import { parserCodeVisual } from "./codeParser";
  11. function parseActivityData (data, ignore_logs=false) {
  12. let algorithm_in_ilm = null;
  13. if (data.split("\n::algorithm::")[1]) {
  14. algorithm_in_ilm = data.split("\n::algorithm::")[1].split("\n::logs::")[0];
  15. const logs = data.split("\n::algorithm::")[1].split("\n::logs::")[1];
  16. if (logs != null && ignore_logs == false) {
  17. try {
  18. parseLogs(logs);
  19. } catch (e) {}
  20. }
  21. }
  22. let content;
  23. try {
  24. content = JSON.parse(data.split("\n::algorithm::")[0]);
  25. content["algorithm_in_ilm"] = algorithm_in_ilm;
  26. } catch (e) {
  27. console.error(e);
  28. return Maybe.none();
  29. }
  30. return Maybe.some(content);
  31. }
  32. function configAuxiliar (obj_config) {
  33. return new Map(Object.keys(obj_config).map(key => [key, obj_config[key]]))
  34. }
  35. function setActivityConfig (config_json) {
  36. ivprogCore.Config.activity_commands = configAuxiliar(config_json.commands);
  37. ivprogCore.Config.activity_functions = configAuxiliar(config_json.functions);
  38. ivprogCore.Config.activity_datatypes = configAuxiliar(config_json.datatypes);
  39. ivprogCore.Config.activity_filter = configAuxiliar(config_json.filter);
  40. ivprogCore.Config.activity_programming_type = configAuxiliar(config_json.programming);
  41. }
  42. // @Calledby: js/iassign-integration-functions.js!prepareActivityToStudent(.)
  43. export function setPreviousAlgorithm (code) {
  44. var code_obj = null;
  45. try {
  46. code_obj = ivprogCore.parseCode(code);
  47. var result = parserCodeVisual(code_obj); // in js/util/codeParser.js
  48. if (result == null) { // force exception to "iassign-integration-functions.js" identify error in the current format try
  49. console.log("js/util/iassignHelpers.js!setPreviousAlgorithm(code): returned empty");
  50. return null;
  51. // throw new Error("js/util/iassignHelpers.js!setPreviousAlgorithm(code): returned empty");
  52. }
  53. console.log("js/util/iassignHelpers.js!setPreviousAlgorithm(code): parserCodeVisual(.) returned: " + result);
  54. return result;
  55. } catch (e) {
  56. showInvalidData()
  57. console.log(e)
  58. return
  59. }
  60. }
  61. export function prepareActivityToStudentHelperJSON (ilm_cont) {
  62. setTestCases(ilm_cont.test_cases)
  63. setActivityConfig(ilm_cont.settings)
  64. if (ilm_cont.code)
  65. setPreviousAlgorithm(ilm_cont.code)
  66. else
  67. if (ilm_cont.algorithm)
  68. setPreviousAlgorithm(ilm_cont.algorithm)
  69. }
  70. export function prepareActivityToStudentHelper (ilm_cont, ignore_logs=false) {
  71. const maybe_content = parseActivityData(ilm_cont, ignore_logs);
  72. return maybe_content.map((content) => {
  73. const testCases = content.testcases;
  74. setTestCases(testCases);
  75. let prog_type = null;
  76. if (content.settings_programming_type) {
  77. prog_type = content.settings_programming_type[0].value;
  78. } else {
  79. prog_type = "visual";
  80. }
  81. return {
  82. settingsProgrammingType: prog_type,
  83. settingsDataTypes: content.settings_data_types,
  84. settingsCommands: content.settings_commands,
  85. settingsFunctions: content.settings_functions,
  86. algorithmInIlm: content.algorithm_in_ilm,
  87. settingsFilter: content.settings_filter,
  88. };
  89. });
  90. }
  91. function compareArray (a, b) {
  92. for (let i = 0; i < a.length; ++i) {
  93. const elementA = a[i];
  94. const elementB = b[i];
  95. if (elementA != elementB) {
  96. return false;
  97. }
  98. }
  99. return true;
  100. }
  101. function compareTestcases (original, student) {
  102. if (original.length != student.length) {
  103. return false;
  104. }
  105. for (let i = 0; i < original.length; ++i) {
  106. const elementO = original[i];
  107. const elementS = student[i];
  108. if (!compareArray(elementO.input, elementS.input)) {
  109. return false;
  110. }
  111. if (!compareArray(elementO.output, elementS.output)) {
  112. return false;
  113. }
  114. }
  115. return true;
  116. }
  117. export function autoEval (originalData, callback) {
  118. const code = generate();
  119. //console.debug(code);
  120. const original = parseActivityData(originalData).getOrElse(undefined);
  121. if (original == null) {
  122. alert("iAssign did not provide the original activity data!");
  123. return callback(null);
  124. }
  125. if (code == null) {
  126. return callback(-1); // @FeedbackConvention Casos de teste vazios
  127. } else {
  128. if (!compareTestcases(original.testcases, getTestCases())) {
  129. return callback(-2); // @FeedbackConvention Casos de teste alterados pelo aluno
  130. }
  131. try {
  132. const ast_code = SemanticAnalyser.analyseFromSource(code);
  133. const con = new TestConsole([]);
  134. const autoAssessment = new IVProgAssessment(ast_code, original.testcases, con);
  135. autoAssessment.runTest().then((grade) => callback(grade)).catch((err) => {
  136. console.log(err);
  137. callback(-5); // @FeedbackConvention Falha na execução
  138. });
  139. } catch (e) {
  140. console.error(e);
  141. callback(-5);
  142. }
  143. }
  144. }