| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- package com.seecoder.dataanalysis.analysis.impl;
- import com.seecoder.dataanalysis.analysis.EvalDataAnalysisService;
- import com.seecoder.dataanalysis.data.dao.competency.CompetencyTreeDao;
- import com.seecoder.dataanalysis.data.dao.eval.EvalExamInfoDao;
- import com.seecoder.dataanalysis.data.dao.eval.EvalExamRecordDao;
- import com.seecoder.dataanalysis.data.dao.eval.QuestionDao;
- import com.seecoder.dataanalysis.data.entity.competency.*;
- import com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo;
- import com.seecoder.dataanalysis.data.entity.eval.EvalExamRecord;
- import com.seecoder.dataanalysis.data.entity.eval.Question;
- import com.seecoder.dataanalysis.logic.question.QuestionService;
- import com.sun.xml.internal.bind.v2.TODO;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.text.DecimalFormat;
- import java.util.*;
- /**
- * @author Peng Yiyan
- * @since 2022/02/03
- */
- @Service
- public class EvalDataAnalysisServiceImpl implements EvalDataAnalysisService {
- @Autowired
- private EvalExamRecordDao evalExamRecordDao;
- @Autowired
- private EvalExamInfoDao evalExamInfoDao;
- @Autowired
- private CompetencyTreeDao competencyTreeDao;
- @Autowired
- private QuestionService questionService;
- @Override
- public CompetencyTree getTreeById(int userId){
- Competencies competencies = new Competencies();
- CompetencyTree modelTree = new CompetencyTree(competencies);
- Optional<CompetencyTree> result = competencyTreeDao.findById(userId);
- if(!result.isPresent()){
- System.out.println("该学生的能力树不存在");
- }
- CompetencyTree competencyTree = competencyTreeDao.findById(userId).get();
- modelTree.setUserId(userId);
- modelTree.setTreeScore(competencyTree.getTreeScore());
- List<KSDScore> modelKSD = modelTree.getSubCompetencyTree();
- List<KSDScore> tarKSD = competencyTree.getSubCompetencyTree();
- // for(KSDScore ksdScore : tarKSD){
- // String tarCom = ksdScore.getCompetency();
- // List<KSScore> tarKS = ksdScore.getKSScore();
- // List<DScore> tarD = ksdScore.getDScore();
- //
- // //找到对应的KSD树,开始进行KS和D的匹配
- // for(KSDScore KSDModel : modelKSD){
- // if(KSDModel.getCompetency().equals(tarCom)){
- // KSDModel.setTotalScore(ksdScore.getTotalScore());
- // //进行KS的匹配
- // List<KSScore> modelKS = KSDModel.getKSScore();
- // for(KSScore ksScore : tarKS){
- // String tarSub = ksScore.getKnowledge();
- // List<Double> tarSkillScore = ksScore.getSkillsAndScore();
- //
- // for(KSScore KSModel : modelKS){
- // if(KSModel.getKnowledge().equals(tarSub)){
- // List<Double> after = KSModel.getSkillsAndScore();
- // for(int i=0;i<tarSkillScore.size();i++){
- // after.set(i,tarSkillScore.get(i));
- // }
- // KSModel.setSkillsAndScore(after);
- // break;
- // }
- // }
- // }
- // KSDModel.setKSScore(modelKS);
- // //进行D的匹配
- // List<DScore> modelD = KSDModel.getDScore();
- // for(DScore dScore : tarD){
- // String tarName = dScore.getName();
- //
- // for(DScore DModel : modelD){
- // if(DModel.getName().equals(tarName)){
- // DModel.setScore(dScore.getScore());
- // break;
- // }
- // }
- // }
- // KSDModel.setDScore(modelD);
- // break;
- // }
- // }
- // }
- modelTree.setSubCompetencyTree(modelKSD);
- return modelTree;
- }
- @Override
- public CompetencyTree getTreeAfterExam(int recordId) {
- EvalExamRecord evalExamRecord = evalExamRecordDao.findById(recordId).get();
- Optional<EvalExamInfo> result1 = evalExamInfoDao.findById(evalExamRecord.getExamId());
- if (!result1.isPresent()) {
- System.out.println("考试信息不存在");
- return null;
- }
- EvalExamInfo evalExamInfo = evalExamInfoDao.findById(evalExamRecord.getExamId()).get();
- CompetencyTree competencyTree;
- Optional<CompetencyTree> result2 = competencyTreeDao.findById(evalExamRecord.getUserId());
- if (!result2.isPresent()) {
- //若查找不到能力树就新建一棵
- competencyTree = new CompetencyTree(evalExamRecord.getUserId());
- } else {
- competencyTree = competencyTreeDao.findById(evalExamRecord.getUserId()).get();
- }
- //数据取完,开始进行KSD分析和入库
- List<KSDScore> subTree = competencyTree.getSubCompetencyTree();
- //难度由1-5,分别对应1.0, 1.25, 1.5, 1.75, 2.0的得分系数
- Integer difficulty = evalExamInfo.getDifficulty();
- String disposition = evalExamInfo.getDisposition();
- // System.out.println(competencyTree);
- Double tree_Score = competencyTree.getTreeScore();
- double[] difficulty_percent = new double[]{1.0, 1.25, 1.5, 1.75, 2.0};
- //得到学生所有题目的得分
- Map<String, Double> studentScores = evalExamRecord.getErrorQuestions();
- Map<String, Double> questionAndScore = evalExamInfo.getQuestionAndScore();
- //修改成不初始化,而是逐条添加的模式,对每一题进行分析入库
- for (Map.Entry<String, Double> entry : studentScores.entrySet()) {
- String questionId = entry.getKey();
- Question question = questionService.getQuestionById(questionId);
- List<String> knowledgeList = question.getCompetencies();
- Integer weight = question.getWeight();
- //能力树中的加分 = 学生得分 * 试卷难度
- Double addScore = difficulty_percent[difficulty - 1] * studentScores.get(questionId);
- //增加能力树总分,注意,每个competency都会加分
- tree_Score += (addScore * knowledgeList.size());
-
- for(int i=0;i<knowledgeList.size();i++){
- String[] coms = knowledgeList.get(i).split("\\.");
- String com1 = coms[0];
- dfs(subTree,disposition,weight,addScore,"",com1);
- int index1 = 0;
- if(coms.length > 1){
- String com2 = coms[1];
- for(;index1<subTree.size();index1++){
- if(subTree.get(index1).getCompetency().equals(com1)){
- break;
- }
- }
- dfs(subTree.get(index1).getChildren(),disposition,weight,addScore,com1+".",com2);
- }
- if(coms.length > 2){
- String com2 = coms[1];
- String com3 = coms[2];
- // System.out.println(com1+com2+com3);
- int index2 = 0;
- for(;index2<subTree.get(index1).getChildren().size();index2++){
- // System.out.println(subTree.get(index1).getChildren().get(index2).getCompetency());
- if(subTree.get(index1).getChildren().get(index2).getCompetency().split("\\.")[1].equals(com2)){
- break;
- }
- }
- dfs(subTree.get(index1).getChildren().get(index2).getChildren(),disposition,weight,addScore,com1+"."+com2+".",com3);
- }
- }
- }
- //处理完考试中的每个问题后,更新能力树
- competencyTree.setTreeScore(tree_Score);
- competencyTree.setSubCompetencyTree(subTree);
- competencyTreeDao.save(competencyTree);
- return competencyTree;
- }
- public void dfs(List<KSDScore> sub,String disposition,Integer weight,Double addScore,String pre,String com){
- // System.out.println("start: "+com);
- boolean existCom = false;
- KSDScore changeKSD = new KSDScore();
- for (KSDScore ksdScore : sub) {
- System.out.println(ksdScore.getCompetency());
- if (ksdScore.getCompetency().equals(pre+com)) {
- existCom = true;
- changeKSD = ksdScore;
- break;
- }
- }
- if (!existCom) {
- List<DScore> addD = new ArrayList<>();
- Double[] ds = new Double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
- List<Double> addS = Arrays.asList(ds);
- List<KSDScore> addChild = new ArrayList<>();
- changeKSD.setCompetency(pre+com);
- changeKSD.setTotalScore(0.0);
- changeKSD.setSkillsAndScores(addS);
- changeKSD.setDScore(addD);
- changeKSD.setChildren(addChild);
- }
- Double totalScore = changeKSD.getTotalScore();
- totalScore += addScore;
- changeKSD.setTotalScore(totalScore);
- //增加Skills
- List<Double> skillsAndScore = changeKSD.getSkillsAndScores();
- Double skillScore = skillsAndScore.get(weight-1);
- skillScore += addScore;
- skillsAndScore.set(weight-1,skillScore);
- changeKSD.setSkillsAndScores(skillsAndScore);
- //增加Disposition
- if(disposition != null){
- boolean existD = false;
- List<DScore> subD = changeKSD.getDScore();
- DScore changeD = new DScore();
- for (DScore dScore : subD) {
- if (dScore.getName().equals(disposition)) {
- existD = true;
- changeD = dScore;
- break;
- }
- }
- if (!existD) {
- changeD.setName(disposition);
- changeD.setScore(0.0);
- }
- Double addDScore = addScore + changeD.getScore();
- changeD.setScore(addDScore);
- //需要增加新建的D子分支
- if (!existD) {
- subD.add(changeD);
- }
- changeKSD.setDScore(subD);
- }else {
- System.out.println("disposition信息不存在");
- }
- if (!existCom) {
- sub.add(changeKSD);
- }
- }
- @Override
- public Map<String, Double> getStudentErrorQuestions(int userId){
- List<EvalExamRecord> evalExamRecordList = evalExamRecordDao.findByUserId(userId);
- Map<String,Double> res = new HashMap<>();
- for(EvalExamRecord evalExamRecord : evalExamRecordList){
- Optional<EvalExamInfo> result = evalExamInfoDao.findById(evalExamRecord.getExamId());
- if(!result.isPresent()){
- System.out.println("找不到对应考试信息");
- continue;
- }
- EvalExamInfo evalExamInfo = evalExamInfoDao.findById(evalExamRecord.getExamId()).get();
- //获得题目ID和题目分数的对应关系
- Map<String,Double> questionAndScore = evalExamInfo.getQuestionAndScore();
- Map<String,Double> errorQuestions = evalExamRecord.getErrorQuestions();
- for(String questionId : errorQuestions.keySet()){
- // Optional<Question> result = questionDao.findById(questionId);
- // if(!result.isPresent()){
- // System.out.println("题号不存在");
- // continue;
- // }
- Question question = questionService.getQuestionById(questionId);
- //如果题目分数为0,则跳过该题不做分析
- if(questionAndScore.get(questionId) == 0){
- continue;
- }
- // System.out.println(errorQuestions.get(questionId));
- // System.out.println(question.getQuestionScore());
- //如果做过相同的题目,则取最高分
- DecimalFormat df = new DecimalFormat("#.00");
- Double scorePercent = errorQuestions.get(questionId)/questionAndScore.get(questionId);
- if(res.containsKey(questionId)){
- scorePercent = Math.max(scorePercent,res.get(questionId));
- }
- res.put(questionId,Double.valueOf(df.format(scorePercent)));
- }
- }
- return res;
- }
- }
|