EvalDataAnalysisServiceImpl.java 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package com.seecoder.dataanalysis.analysis.impl;
  2. import com.seecoder.dataanalysis.analysis.EvalDataAnalysisService;
  3. import com.seecoder.dataanalysis.data.dao.competency.CompetencyTreeDao;
  4. import com.seecoder.dataanalysis.data.dao.eval.EvalExamInfoDao;
  5. import com.seecoder.dataanalysis.data.dao.eval.EvalExamRecordDao;
  6. import com.seecoder.dataanalysis.data.dao.eval.QuestionDao;
  7. import com.seecoder.dataanalysis.data.entity.competency.CompetencyTree;
  8. import com.seecoder.dataanalysis.data.entity.competency.DScore;
  9. import com.seecoder.dataanalysis.data.entity.competency.KSDScore;
  10. import com.seecoder.dataanalysis.data.entity.competency.KSScore;
  11. import com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo;
  12. import com.seecoder.dataanalysis.data.entity.eval.EvalExamRecord;
  13. import com.seecoder.dataanalysis.data.entity.eval.Question;
  14. import com.sun.xml.internal.bind.v2.TODO;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.stereotype.Service;
  17. import java.util.*;
  18. /**
  19. * @author Peng Yiyan
  20. * @since 2022/02/03
  21. */
  22. @Service
  23. public class EvalDataAnalysisServiceImpl implements EvalDataAnalysisService {
  24. @Autowired
  25. private EvalExamRecordDao evalExamRecordDao;
  26. @Autowired
  27. private EvalExamInfoDao evalExamInfoDao;
  28. @Autowired
  29. private CompetencyTreeDao competencyTreeDao;
  30. @Autowired
  31. private QuestionDao questionDao;
  32. @Override
  33. public CompetencyTree getTreeById(int userId){
  34. //TODO 和ModelTree进行合并,空值补0,返回可以用于可视化的结果
  35. return null;
  36. }
  37. @Override
  38. public CompetencyTree getTreeAfterExam(int exam_id){
  39. //TODO 测试检查
  40. EvalExamRecord evalExamRecord = evalExamRecordDao.findById(exam_id).get();
  41. EvalExamInfo evalExamInfo = evalExamInfoDao.findById(exam_id).get();
  42. CompetencyTree competencyTree;
  43. Optional<CompetencyTree> result = competencyTreeDao.findById(evalExamRecord.getUserId());
  44. if(!result.isPresent()){
  45. competencyTree = new CompetencyTree(evalExamRecord.getUserId());
  46. }else {
  47. competencyTree = competencyTreeDao.findById(evalExamRecord.getUserId()).get();
  48. }
  49. //数据取完,开始进行KSD分析和入库
  50. List<KSDScore> subTree = competencyTree.getSubCompetencyTree();
  51. Integer difficulty = evalExamInfo.getDifficulty();
  52. String disposition = evalExamInfo.getDisposition();
  53. Double tree_Score = competencyTree.getTreeScore();
  54. double[] difficulty_percent = new double[]{1.0,1.25,1.5,1.75,2.0};
  55. //得到学生所有题目的得分
  56. Map<String, Double> studentScores = evalExamRecord.getErrorQuestions();
  57. // Map<String,Double> questionAndScore = evalExamInfo.getQuestionAndScore();
  58. //修改成不初始化,而是逐条添加的模式
  59. for(Map.Entry<String,Double> entry : studentScores.entrySet()){
  60. String questionId = entry.getKey();
  61. Question question = questionDao.findById(questionId).get();
  62. //能力树中的加分 = 学生得分 * 试卷难度
  63. Double addScore = difficulty_percent[difficulty] * studentScores.get(questionId);
  64. //增加能力树总分
  65. tree_Score += addScore;
  66. for(int i=0;i<question.getCompetencies().size();i++){
  67. String competency = question.getCompetencies().get(i);
  68. KSScore ksScoreMessage = question.getKsScores().get(i);
  69. //判定当前的subTree中是否添加过该分支,若添加过则直接修改,否则要新建分支
  70. boolean existCom = false;
  71. KSDScore changeKSDScore = new KSDScore();
  72. //根据competency找大分类
  73. for(KSDScore ksdScore : subTree){
  74. //competency大分支存在
  75. if(ksdScore.getCompetency().equals(competency)){
  76. existCom = true;
  77. changeKSDScore = ksdScore;
  78. break;
  79. }
  80. }
  81. //competency大分支不存在,需要添加
  82. if(existCom == false){
  83. changeKSDScore.setCompetency(competency);
  84. changeKSDScore.setTotalScore(0.0);
  85. List<KSScore> addKs = new ArrayList<>();
  86. List<DScore> addD = new ArrayList<>();
  87. changeKSDScore.setKSScore(addKs);
  88. changeKSDScore.setDScore(addD);
  89. }
  90. //增加该KSD子树的分数
  91. Double total_score = changeKSDScore.getTotalScore();
  92. total_score += addScore;
  93. changeKSDScore.setTotalScore(total_score);
  94. //开始处理KSScore,记录子分支是否存在
  95. boolean existSubCom = false;
  96. //在对应的competency下进行下一步小分类
  97. List<KSScore> subKS = changeKSDScore.getKSScore();
  98. KSScore changeKSScore = new KSScore();
  99. for(KSScore ksScore : subKS){
  100. if(ksScore.getKnowledge().equals(ksScoreMessage.getKnowledge())){
  101. existSubCom = true;
  102. changeKSScore = ksScore;
  103. break;
  104. }
  105. }
  106. //sub小分支不存在,需要添加并对分支名称和分数进行初始化
  107. if(existSubCom == false){
  108. changeKSScore.setKnowledge(ksScoreMessage.getKnowledge());
  109. changeKSScore.setSkillsAndScore(Arrays.asList(new Double[]{0.0,0.0,0.0,0.0,0.0,0.0}));
  110. }
  111. List<Double> skills = changeKSScore.getSkillsAndScore();
  112. for(int j=0;j<skills.size();j++){
  113. Double score = ksScoreMessage.getSkillsAndScore().get(j) * addScore + skills.get(i);
  114. skills.set(j,score);
  115. }
  116. changeKSScore.setSkillsAndScore(skills);
  117. //需要增加新建的KS子分支
  118. if(existSubCom == false){
  119. subKS.add(changeKSScore);
  120. }
  121. //开始处理DScore,记录该品质是否存在
  122. boolean existD = false;
  123. List<DScore> subD = changeKSDScore.getDScore();
  124. DScore changeDScore = new DScore();
  125. for(DScore dScore : subD){
  126. if(dScore.getName().equals(disposition)){
  127. existD = true;
  128. changeDScore = dScore;
  129. break;
  130. }
  131. }
  132. if(existD == false){
  133. changeDScore.setName(disposition);
  134. changeDScore.setScore(0.0);
  135. }
  136. Double addDScore = addScore + changeDScore.getScore();
  137. changeDScore.setScore(addDScore);
  138. //需要增加新建的D子分支
  139. if(existD == false){
  140. subD.add(changeDScore);
  141. }
  142. //处理完KS分支和D分支
  143. changeKSDScore.setKSScore(subKS);
  144. changeKSDScore.setDScore(subD);
  145. if(existCom == false){
  146. subTree.add(changeKSDScore);
  147. }
  148. }
  149. }
  150. //处理完考试中的每个问题后,更新能力树
  151. competencyTree.setTreeScore(tree_Score);
  152. competencyTree.setSubCompetencyTree(subTree);
  153. competencyTreeDao.save(competencyTree);
  154. return competencyTree;
  155. }
  156. @Override
  157. public Map<String, Double> getStudentErrorQuestions(int userId){
  158. List<EvalExamRecord> evalExamRecordList = evalExamRecordDao.findByUserId(userId);
  159. Map<String,Double> res = new HashMap<>();
  160. for(EvalExamRecord evalExamRecord : evalExamRecordList){
  161. Map<String,Double> errorQuestions = evalExamRecord.getErrorQuestions();
  162. for(String questionId : errorQuestions.keySet()){
  163. Optional<Question> result = questionDao.findById(questionId);
  164. if(!result.isPresent()){
  165. System.out.println("题号不存在");
  166. continue;
  167. }
  168. Question question = questionDao.findById(questionId).get();
  169. //如果题目分数为0,则跳过该题不做分析
  170. if(question.getQuestionScore() == 0){
  171. continue;
  172. }
  173. Double scorePercent = errorQuestions.get(questionId) / question.getQuestionScore();
  174. res.put(questionId,res.getOrDefault(questionId,0.0)+scorePercent);
  175. }
  176. }
  177. return res;
  178. }
  179. }