|
@@ -10,19 +10,22 @@ import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
|
10
|
10
|
import com.xhkjedu.smarking.model.exam.MsClassStudent;
|
11
|
11
|
import com.xhkjedu.smarking.model.paper.MsPaper;
|
12
|
12
|
import com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion;
|
|
13
|
+import com.xhkjedu.smarking.model.report.reportclass.MsrClassQtype;
|
13
|
14
|
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestion;
|
14
|
15
|
import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestionObj;
|
15
|
16
|
import com.xhkjedu.smarking.model.report.reportother.MsrReportparam;
|
16
|
17
|
import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
|
17
|
|
-import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectSectionQuestion;
|
|
18
|
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionSection;
|
18
|
19
|
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
|
19
|
20
|
import com.xhkjedu.smarking.utils.MarkingUtil;
|
|
21
|
+import com.xhkjedu.smarking.vo.report.reportother.RankGroupVo;
|
20
|
22
|
import com.xhkjedu.smarking.vo.report.reportother.SzJsonVo;
|
21
|
23
|
import com.xhkjedu.utils.N_Utils;
|
22
|
24
|
import org.springframework.stereotype.Service;
|
23
|
25
|
|
24
|
26
|
import javax.annotation.Resource;
|
25
|
27
|
import java.util.ArrayList;
|
|
28
|
+import java.util.Arrays;
|
26
|
29
|
import java.util.List;
|
27
|
30
|
import java.util.Map;
|
28
|
31
|
import java.util.stream.Collectors;
|
|
@@ -47,128 +50,140 @@ public class ReportGenerateQuestionService {
|
47
|
50
|
@Resource
|
48
|
51
|
private MsPaperStudentMapper msPaperStudentMapper;
|
49
|
52
|
|
50
|
|
- public void generateQuestion(Integer examid,Integer exammode){
|
51
|
|
- //查询所有学生试题
|
|
53
|
+ public void generateQuestion(Integer examid, Integer exammode) {
|
|
54
|
+ // 查询所有学生试题
|
52
|
55
|
List<MsPaperStudentQuestion> stuQuestions = msPaperStudentQuestionMapper.listAllStuQuesByExamid(examid);
|
53
|
56
|
List<MsClassStudent> classStudents = msClassStudentMapper.listStudentByExamId(examid);
|
54
|
57
|
List<MsPaper> subjects = msSubjectMapper.listReportSubject(examid, exammode);
|
55
|
58
|
List<MsrStudent> stuPapers = msPaperStudentMapper.listPaperStudentByExamId(examid, null);
|
56
|
|
- //获取考试参数
|
57
|
|
- List<MsrReportparam> params = msrReportparamMapper.listReportparamByRpbelong(examid,"quesummary",null);
|
|
59
|
+ // 获取考试参数
|
|
60
|
+ List<MsrReportparam> params = msrReportparamMapper.listReportparamByRpbelong(examid, "quesummary", null);
|
58
|
61
|
|
59
|
|
- //根据科目进行区分
|
60
|
|
- for(MsPaper subject : subjects){
|
|
62
|
+ // 根据科目进行区分
|
|
63
|
+ for (MsPaper subject : subjects) {
|
61
|
64
|
String subjectid = subject.getSubjectid();
|
62
|
|
- //获取科目下所有学生试题
|
63
|
|
- List<MsPaperStudentQuestion> subjectStuQuestions = stuQuestions.stream().filter(stuQuestion -> stuQuestion.getSubjectid().equals(subjectid)).collect(Collectors.toList());
|
64
|
|
- //科目下所有班级学生
|
|
65
|
+ // 获取科目下所有学生试题
|
|
66
|
+ List<MsPaperStudentQuestion> subjectStuQuestions =
|
|
67
|
+ stuQuestions.stream().filter(stuQuestion -> stuQuestion.getSubjectid().equals(subjectid)).collect(Collectors.toList());
|
|
68
|
+ // 科目下所有班级学生
|
65
|
69
|
List<MsClassStudent> subjectClassStudents = classStudents.stream().filter(classStudent -> classStudent.getSubjectid().equals(subjectid)).collect(Collectors.toList());
|
66
|
|
- //获取试卷中所有小题基础信息包含大题信息
|
|
70
|
+ // 获取试卷中所有小题基础信息包含大题信息
|
67
|
71
|
List<MsPaperQtypeQuestion> questions = msPaperQtypeQuestionMapper.listQuestionsForReport(subject.getMpid());
|
68
|
|
- //获取科目参数
|
|
72
|
+ // 获取科目参数
|
69
|
73
|
List<MsrReportparam> subjectParams = params.stream().filter(p -> p.getSubjectid().equals(subjectid)).collect(Collectors.toList());
|
70
|
|
- //获取学生科目得分
|
|
74
|
+ // 获取学生科目得分
|
71
|
75
|
List<MsrStudent> subjectStuPapers = stuPapers.stream().filter(p -> p.getSubjectid().equals(subjectid)).collect(Collectors.toList());
|
72
|
|
-
|
73
|
|
- //处理小题
|
74
|
|
- handleQuestion(subjectStuQuestions,subjectClassStudents,questions,subjectParams,examid,subjectid);
|
|
76
|
+ // 获取学生科目得分-科目默认分段学生
|
|
77
|
+ List<MsrSubjectQuestionSection> subjectSectionQuestions = subjectSectionForQuestion(subjectStuPapers, subject.getPscore());
|
|
78
|
+ // 处理小题
|
|
79
|
+ handleQuestion(subjectStuQuestions, subjectClassStudents, questions, subjectParams, subjectSectionQuestions, examid, subjectid);
|
|
80
|
+ //处理题型
|
|
81
|
+ handleQtype(subjectStuQuestions, subjectClassStudents, questions, subjectParams, examid, subjectid);
|
75
|
82
|
}
|
76
|
83
|
}
|
77
|
84
|
|
78
|
|
- //处理单个试题分析
|
79
|
|
- private void handleQuestion(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsClassStudent> subjectClassStudents,List<MsPaperQtypeQuestion> questions,List<MsrReportparam> params,Integer examid,String subjectid){
|
|
85
|
+ // 单个试题分析
|
|
86
|
+ private void handleQuestion(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
|
|
87
|
+ List<MsrReportparam> params, List<MsrSubjectQuestionSection> subjectSectionQuestions, Integer examid, String subjectid) {
|
80
|
88
|
|
81
|
|
- List<MsrClassQuestion> saveQuestions = new ArrayList<>();//小题分析
|
82
|
|
- List<MsrClassQuestionObj> saveQuestionObjs = new ArrayList<>();//小题-客观题选项分析
|
|
89
|
+ List<MsrClassQuestion> saveQuestions = new ArrayList<>();// 小题分析
|
|
90
|
+ List<MsrClassQuestionObj> saveQuestionObjs = new ArrayList<>();// 小题-客观题选项分析
|
|
91
|
+ List<MsrSubjectQuestionSection> saveSectionQuestions = new ArrayList<>();// 学科分段之间学生在该题的整体得分率
|
83
|
92
|
|
84
|
|
- //处理小题信息
|
85
|
|
- for(MsPaperQtypeQuestion question : questions){
|
86
|
|
- //获取第一小题所有作答情况,全校作答情况
|
|
93
|
+ // 处理小题信息
|
|
94
|
+ for (MsPaperQtypeQuestion question : questions) {
|
|
95
|
+ // 获取第一小题所有作答情况,全校作答情况
|
87
|
96
|
List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> q.getMptqid().equals(question.getMptqid())).collect(Collectors.toList());
|
88
|
|
- int stunum = stuQuestions.size();//学生数量
|
89
|
|
- Double sumQScore = question.getQscore() * stunum;//小题得分
|
90
|
|
- List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());//所有学生得分
|
|
97
|
+ int stunum = stuQuestions.size();// 学生数量
|
|
98
|
+ Double sumQScore = question.getQscore() * stunum;// 小题得分
|
|
99
|
+ List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分
|
91
|
100
|
|
92
|
|
- Double maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);//最高分
|
93
|
|
- Double minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);//最低分
|
94
|
|
- Double avgScore = MarkingUtil.calculateAverage(stuScores);//平均分
|
95
|
|
- Double avgScoreRate = MarkingUtil.calculateRate(avgScore,sumQScore);//平均得分率
|
|
101
|
+ Double maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
|
|
102
|
+ Double minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
|
|
103
|
+ Double avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
|
|
104
|
+ Double avgScoreRate = MarkingUtil.calculateRate(avgScore, sumQScore);// 平均得分率
|
96
|
105
|
|
97
|
106
|
MsrClassQuestion schoolQ = new MsrClassQuestion();
|
98
|
|
- schoolQ.setClassid(0);//全体班级
|
|
107
|
+ schoolQ.setClassid(0);// 全体班级
|
99
|
108
|
schoolQ.setExamid(examid);
|
100
|
109
|
schoolQ.setSubjectid(subjectid);
|
101
|
110
|
schoolQ.setSchoolmaxscore(maxScore);
|
102
|
111
|
schoolQ.setSchoolminscore(minScore);
|
103
|
112
|
schoolQ.setSchoolavgscore(avgScore);
|
104
|
113
|
schoolQ.setSchoolavgrate(avgScoreRate);
|
105
|
|
- //班级试题情况
|
106
|
|
- MsrClassQuestion schoolQue = handleQuestionClass(stuQuestions,question,params,schoolQ);
|
|
114
|
+ // 全校班级试题情况
|
|
115
|
+ MsrClassQuestion schoolQue = questionClass(stuQuestions, question, params, schoolQ);
|
107
|
116
|
saveQuestions.add(schoolQue);
|
108
|
117
|
|
109
|
|
- //班级试题--客观题选项情况
|
|
118
|
+ // 班级试题--客观题选项情况
|
110
|
119
|
MsrClassQuestionObj qobj = new MsrClassQuestionObj();
|
111
|
|
- if(question.getQtype() == 1){
|
|
120
|
+ if (question.getQtype() == 1) {
|
112
|
121
|
qobj.setExamid(examid);
|
113
|
122
|
qobj.setSubjectid(subjectid);
|
114
|
123
|
qobj.setClassid(0);
|
115
|
124
|
qobj.setMptqid(question.getMptqid());
|
116
|
|
- List<MsrClassQuestionObj> qobjList = handleQuestionXuanxiang(stuQuestions,qobj);
|
|
125
|
+ List<MsrClassQuestionObj> qobjList = questionXuanxiang(stuQuestions, qobj);
|
117
|
126
|
saveQuestionObjs.addAll(qobjList);
|
118
|
127
|
}
|
119
|
128
|
|
120
|
|
- //班级试题分析
|
121
|
|
- //获取所有班级
|
|
129
|
+ // 学科分段之间学生在该题的整体得分率
|
|
130
|
+ List<MsrSubjectQuestionSection> sectionQuestions = subjectSectionQuestion(stuQuestions, subjectSectionQuestions, question);
|
|
131
|
+ saveSectionQuestions.addAll(sectionQuestions);
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+ // 班级试题分析
|
|
135
|
+ // 获取所有班级
|
122
|
136
|
List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
|
123
|
|
- for(Integer classid : classIds){
|
124
|
|
- //获取班级下学生id
|
125
|
|
- List<Integer> classStuIds = subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
|
126
|
|
- //获取班级下学生试题
|
|
137
|
+ for (Integer classid : classIds) {
|
|
138
|
+ // 获取班级下学生id
|
|
139
|
+ List<Integer> classStuIds =
|
|
140
|
+ subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
|
|
141
|
+ // 获取班级下学生试题
|
127
|
142
|
List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
|
128
|
143
|
schoolQ.setClassid(classid);
|
129
|
|
- MsrClassQuestion classQue = handleQuestionClass(classStuQuestions,question,params,schoolQ);
|
|
144
|
+ MsrClassQuestion classQue = questionClass(classStuQuestions, question, params, schoolQ);
|
130
|
145
|
saveQuestions.add(classQue);
|
131
|
146
|
|
132
|
|
- //班级试题--客观题选项情况
|
133
|
|
- if(question.getQtype() == 1) {
|
|
147
|
+ // 班级试题--客观题选项情况
|
|
148
|
+ if (question.getQtype() == 1) {
|
134
|
149
|
qobj.setClassid(classid);
|
135
|
|
- List<MsrClassQuestionObj> qobjList = handleQuestionXuanxiang(classStuQuestions,qobj);
|
|
150
|
+ List<MsrClassQuestionObj> qobjList = questionXuanxiang(classStuQuestions, qobj);
|
136
|
151
|
saveQuestionObjs.addAll(qobjList);
|
137
|
152
|
}
|
138
|
153
|
}
|
139
|
154
|
}
|
140
|
155
|
}
|
141
|
156
|
|
142
|
|
- //处理单个试题分析-学校、班级分析
|
143
|
|
- private MsrClassQuestion handleQuestionClass(List<MsPaperStudentQuestion> stuQuestions,MsPaperQtypeQuestion question,List<MsrReportparam> params,MsrClassQuestion schoolQ){
|
144
|
|
- int stunum = stuQuestions.size();//学生数量
|
145
|
|
- Double qScore = question.getQscore();//试题分值
|
146
|
|
- Double sumQScore = question.getQscore() * stunum;//小题得分
|
147
|
|
- List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());//所有学生得分
|
148
|
|
- Double sumStuScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();//综合
|
149
|
|
-
|
150
|
|
- Double maxScore;//最高分
|
151
|
|
- Double minScore;//最低分
|
152
|
|
- Double avgScore;//平均分
|
153
|
|
- Double avgScoreRate;//平均得分率
|
154
|
|
- if(schoolQ.getClassid() == 0){
|
155
|
|
- //代表是校级
|
|
157
|
+ // 单个试题分析-学校、班级分析
|
|
158
|
+ private MsrClassQuestion questionClass(List<MsPaperStudentQuestion> stuQuestions, MsPaperQtypeQuestion question, List<MsrReportparam> params, MsrClassQuestion schoolQ) {
|
|
159
|
+ int stunum = stuQuestions.size();// 学生数量
|
|
160
|
+ Double qScore = question.getQscore();// 试题分值
|
|
161
|
+ Double sumQScore = question.getQscore() * stunum;// 小题得分
|
|
162
|
+ List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分
|
|
163
|
+ Double sumStuScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 综合
|
|
164
|
+
|
|
165
|
+ Double maxScore;// 最高分
|
|
166
|
+ Double minScore;// 最低分
|
|
167
|
+ Double avgScore;// 平均分
|
|
168
|
+ Double avgScoreRate;// 平均得分率
|
|
169
|
+ if (schoolQ.getClassid() == 0) {
|
|
170
|
+ // 代表是校级
|
156
|
171
|
maxScore = schoolQ.getSchoolmaxscore();
|
157
|
172
|
minScore = schoolQ.getSchoolminscore();
|
158
|
173
|
avgScore = schoolQ.getSchoolavgscore();
|
159
|
174
|
avgScoreRate = schoolQ.getSchoolavgrate();
|
160
|
|
- }else{
|
161
|
|
- //指定班级
|
162
|
|
- maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);//最高分
|
163
|
|
- minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);//最低分
|
164
|
|
- avgScore = MarkingUtil.calculateAverage(stuScores);//平均分
|
165
|
|
- avgScoreRate = MarkingUtil.calculateRate(avgScore,sumQScore);//平均得分率
|
|
175
|
+ } else {
|
|
176
|
+ // 指定班级
|
|
177
|
+ maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
|
|
178
|
+ minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
|
|
179
|
+ avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
|
|
180
|
+ avgScoreRate = MarkingUtil.calculateRate(avgScore, sumQScore);// 平均得分率
|
166
|
181
|
}
|
167
|
|
- Double stuScoreRate = MarkingUtil.calculateRate(sumStuScore,sumQScore);//学生得分率
|
|
182
|
+ Double stuScoreRate = MarkingUtil.calculateRate(sumStuScore, sumQScore);// 学生得分率
|
168
|
183
|
MsrClassQuestion classQ = new MsrClassQuestion();
|
169
|
184
|
classQ.setExamid(schoolQ.getExamid());
|
170
|
185
|
classQ.setSubjectid(schoolQ.getSubjectid());
|
171
|
|
- classQ.setClassid(schoolQ.getClassid());//班级id
|
|
186
|
+ classQ.setClassid(schoolQ.getClassid());// 班级id
|
172
|
187
|
classQ.setMptqid(question.getMptqid());
|
173
|
188
|
classQ.setQtype(question.getQtype());
|
174
|
189
|
classQ.setQn(question.getMptqn() + "." + question.getQn());
|
|
@@ -185,39 +200,40 @@ public class ReportGenerateQuestionService {
|
185
|
200
|
classQ.setSchoolavgrate(schoolQ.getSchoolavgrate());
|
186
|
201
|
|
187
|
202
|
classQ.setScorerate(stuScoreRate);
|
188
|
|
- classQ.setScoreratec(MarkingUtil.sub(MarkingUtil.calculateRate(maxScore,qScore),MarkingUtil.calculateRate(minScore,qScore)));//得分率差=最高得分率-最低得分率
|
189
|
|
- classQ.setNd(MarkingUtil.div(stuScoreRate,qScore));//难度
|
190
|
|
- String[] ndStr = handleQuestionNdAndQfd(params,1,classQ.getNd());
|
191
|
|
- classQ.setNdms(ndStr[0]);//难度描述
|
192
|
|
- classQ.setNdfw(ndStr[1]);//难度范围
|
193
|
|
- classQ.setQfd(MarkingUtil.qfd(stuScores));//区分度
|
194
|
|
- String[] qfdStr = handleQuestionNdAndQfd(params,2,classQ.getNd());
|
195
|
|
- classQ.setQfdms(qfdStr[0]);//区分度描述
|
196
|
|
- classQ.setQfdfw(qfdStr[1]);//区分度范围
|
197
|
|
- classQ.setBzc(MarkingUtil.bzc(stuScores));//标准差
|
198
|
|
- classQ.setCyxs(MarkingUtil.div(classQ.getBzc(),avgScore));//差异系数
|
199
|
|
- classQ.setJbzs(MarkingUtil.jbzs(stuScores,stuScoreRate));//鉴别指数
|
200
|
|
- //获取所有满分学生
|
|
203
|
+ classQ.setScoreratec(MarkingUtil.sub(MarkingUtil.calculateRate(maxScore, qScore), MarkingUtil.calculateRate(minScore, qScore)));// 得分率差=最高得分率-最低得分率
|
|
204
|
+ classQ.setNd(MarkingUtil.div(stuScoreRate, qScore));// 难度
|
|
205
|
+ String[] ndStr = questionNdAndQfd(params, 1, classQ.getNd());
|
|
206
|
+ classQ.setNdms(ndStr[0]);// 难度描述
|
|
207
|
+ classQ.setNdfw(ndStr[1]);// 难度范围
|
|
208
|
+ classQ.setQfd(MarkingUtil.qfd(stuScores));// 区分度
|
|
209
|
+ String[] qfdStr = questionNdAndQfd(params, 2, classQ.getQfd());
|
|
210
|
+ classQ.setQfdms(qfdStr[0]);// 区分度描述
|
|
211
|
+ classQ.setQfdfw(qfdStr[1]);// 区分度范围
|
|
212
|
+ classQ.setBzc(MarkingUtil.bzc(stuScores));// 标准差
|
|
213
|
+ classQ.setCyxs(MarkingUtil.div(classQ.getBzc(), avgScore));// 差异系数
|
|
214
|
+ classQ.setJbzs(MarkingUtil.jbzs(stuScores, stuScoreRate));// 鉴别指数
|
|
215
|
+ // 获取所有满分学生
|
201
|
216
|
List<MsPaperStudentQuestion> fullStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore().equals(q.getQscore())).collect(Collectors.toList());
|
202
|
|
- String mfids = fullStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));//满分学生id
|
|
217
|
+ String mfids = fullStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 满分学生id
|
203
|
218
|
classQ.setMfnum(fullStuQuestions.size());
|
204
|
219
|
classQ.setMfrate(MarkingUtil.div(classQ.getMfnum(), stunum));////正确率、满分人数占比
|
205
|
220
|
classQ.setMfids(mfids);
|
206
|
|
- //获取零分学生
|
207
|
|
- List<MsPaperStudentQuestion> lfStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore()==0).collect(Collectors.toList());
|
208
|
|
- String lfids = lfStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));//零分学生id
|
|
221
|
+ // 获取零分学生
|
|
222
|
+ List<MsPaperStudentQuestion> lfStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore() == 0).collect(Collectors.toList());
|
|
223
|
+ String lfids = lfStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 零分学生id
|
209
|
224
|
classQ.setLfnum(lfStuQuestions.size());
|
210
|
|
- classQ.setLfrate(MarkingUtil.div(lfStuQuestions.size(),stunum));////零分人数占比
|
|
225
|
+ classQ.setLfrate(MarkingUtil.div(lfStuQuestions.size(), stunum));////零分人数占比
|
211
|
226
|
classQ.setLfids(lfids);
|
212
|
227
|
return classQ;
|
213
|
228
|
}
|
214
|
|
- //处理单个试题分析-试题难度、区分度
|
215
|
|
- private String[] handleQuestionNdAndQfd(List<MsrReportparam> params,Integer rptype,Double nd){
|
216
|
|
- //获取难度或者区分度
|
217
|
|
- MsrReportparam ndParam = params.stream().filter(p -> p.getRptype().equals(rptype)).findFirst().orElse(null);//难度
|
|
229
|
+
|
|
230
|
+ // 单个试题分析-试题难度、区分度
|
|
231
|
+ private String[] questionNdAndQfd(List<MsrReportparam> params, Integer rptype, Double nd) {
|
|
232
|
+ // 获取难度或者区分度
|
|
233
|
+ MsrReportparam ndParam = params.stream().filter(p -> p.getRptype().equals(rptype)).findFirst().orElse(null);// 难度
|
218
|
234
|
String ndms = "";
|
219
|
235
|
String ndfw = "";
|
220
|
|
- if(ndParam!= null){
|
|
236
|
+ if (ndParam != null) {
|
221
|
237
|
List<SzJsonVo> szList = JSON.parseArray(ndParam.getSzjson(), SzJsonVo.class);
|
222
|
238
|
for (SzJsonVo sz : szList) {
|
223
|
239
|
if (nd == 1 && sz.getMaxvalue() == 1) {
|
|
@@ -228,21 +244,22 @@ public class ReportGenerateQuestionService {
|
228
|
244
|
ndms = sz.getDjkey();
|
229
|
245
|
ndfw = "[0" + "~" + sz.getMaxvalue() + ")";
|
230
|
246
|
break;
|
231
|
|
- } else if(nd >= sz.getMinvalue() && nd < sz.getMaxvalue()) {
|
|
247
|
+ } else if (nd >= sz.getMinvalue() && nd < sz.getMaxvalue()) {
|
232
|
248
|
ndms = sz.getDjkey();
|
233
|
249
|
ndfw = "[" + sz.getMinvalue() + "~" + sz.getMaxvalue() + ")";
|
234
|
250
|
break;
|
235
|
251
|
}
|
236
|
252
|
}
|
237
|
253
|
}
|
238
|
|
- return new String[]{ndms,ndfw};
|
|
254
|
+ return new String[]{ndms, ndfw};
|
239
|
255
|
}
|
240
|
|
- //处理单个试题分析-客观题选项情况
|
241
|
|
- private List<MsrClassQuestionObj> handleQuestionXuanxiang(List<MsPaperStudentQuestion> stuQuestions,MsrClassQuestionObj questionObj){
|
242
|
|
- Map<String,List<MsPaperStudentQuestion>> optionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStuanswer));
|
|
256
|
+
|
|
257
|
+ // 单个试题分析-客观题选项情况
|
|
258
|
+ private List<MsrClassQuestionObj> questionXuanxiang(List<MsPaperStudentQuestion> stuQuestions, MsrClassQuestionObj questionObj) {
|
|
259
|
+ Map<String, List<MsPaperStudentQuestion>> optionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStuanswer));
|
243
|
260
|
int totalNum = stuQuestions.size();
|
244
|
261
|
List<MsrClassQuestionObj> qobjList = new ArrayList<>();
|
245
|
|
- for(Map.Entry<String,List<MsPaperStudentQuestion>> entry : optionMap.entrySet()){
|
|
262
|
+ for (Map.Entry<String, List<MsPaperStudentQuestion>> entry : optionMap.entrySet()) {
|
246
|
263
|
String option = entry.getKey();
|
247
|
264
|
List<MsPaperStudentQuestion> optionStuQuestions = entry.getValue();
|
248
|
265
|
|
|
@@ -251,13 +268,13 @@ public class ReportGenerateQuestionService {
|
251
|
268
|
qobj.setSubjectid(questionObj.getSubjectid());
|
252
|
269
|
qobj.setClassid(questionObj.getClassid());
|
253
|
270
|
qobj.setMptqid(questionObj.getMptqid());
|
254
|
|
- if(N_Utils.isNotEmpty(option)){
|
|
271
|
+ if (N_Utils.isNotEmpty(option)) {
|
255
|
272
|
qobj.setXxda(option);
|
256
|
|
- }else{
|
|
273
|
+ } else {
|
257
|
274
|
qobj.setXxda("未选");
|
258
|
275
|
}
|
259
|
276
|
qobj.setXxnum(optionStuQuestions.size());
|
260
|
|
- qobj.setXxrate(MarkingUtil.calculateRate(optionStuQuestions.size(),totalNum));
|
|
277
|
+ qobj.setXxrate(MarkingUtil.calculateRate(optionStuQuestions.size(), totalNum));
|
261
|
278
|
String stuids = optionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(","));
|
262
|
279
|
qobj.setStuids(stuids);
|
263
|
280
|
qobjList.add(qobj);
|
|
@@ -265,15 +282,151 @@ public class ReportGenerateQuestionService {
|
265
|
282
|
return qobjList;
|
266
|
283
|
}
|
267
|
284
|
|
268
|
|
- //处理科目分段-默认5分一段为后续试题做准备
|
269
|
|
- private void handleSubjectSectionForQuestion(List<MsrStudent> StuPapers,Double pscore){
|
270
|
|
- //把科目总分分段,默认5分一段
|
271
|
|
- List<int[]> fdList = MarkingUtil.fdScore(pscore,5);
|
272
|
|
- List<MsrSubjectSectionQuestion> sections = new ArrayList<>();
|
273
|
|
- for(int[] fd : fdList){
|
274
|
|
- //获取学生得分在指定区间的学生
|
275
|
|
- List<MsrStudent> fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd[0] && s.getStuscore() < fd[1]).collect(Collectors.toList());
|
276
|
|
- //计算分段平均分
|
|
285
|
+ // 单个试题-科目分段-默认5分一段为后续试题在段上学生得分率做准备
|
|
286
|
+ private List<MsrSubjectQuestionSection> subjectSectionForQuestion(List<MsrStudent> StuPapers, Double pscore) {
|
|
287
|
+ // 把科目总分分段,默认5分一段
|
|
288
|
+ List<RankGroupVo> fdList = MarkingUtil.fdScore(pscore, 5);
|
|
289
|
+ List<MsrSubjectQuestionSection> sections = new ArrayList<>();
|
|
290
|
+ MsrStudent fdStuPaper = StuPapers.get(0);
|
|
291
|
+ for (RankGroupVo fd : fdList) {
|
|
292
|
+ // 获取学生得分在指定区间的学生
|
|
293
|
+ List<MsrStudent> fdStuPapers;
|
|
294
|
+ if (fd.getMaxvalue() == pscore) {
|
|
295
|
+ fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() <= fd.getMaxvalue()).collect(Collectors.toList());
|
|
296
|
+ } else {
|
|
297
|
+ fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
|
|
298
|
+ }
|
|
299
|
+
|
|
300
|
+ MsrSubjectQuestionSection question = new MsrSubjectQuestionSection();
|
|
301
|
+ question.setExamid(fdStuPaper.getExamid());
|
|
302
|
+ question.setSubjectid(fdStuPaper.getSubjectid());
|
|
303
|
+ question.setFdfw(fd.getGroupname());
|
|
304
|
+ question.setFdnum(fdStuPapers.size());
|
|
305
|
+ question.setFdids(fdStuPapers.stream().map(s -> s.getStudentid().toString()).collect(Collectors.joining(",")));
|
|
306
|
+ sections.add(question);
|
|
307
|
+ }
|
|
308
|
+ return sections;
|
|
309
|
+ }
|
|
310
|
+
|
|
311
|
+ // 单个试题分析-科目分段区间得分率
|
|
312
|
+ private List<MsrSubjectQuestionSection> subjectSectionQuestion(List<MsPaperStudentQuestion> stuQuestions, List<MsrSubjectQuestionSection> sections,
|
|
313
|
+ MsPaperQtypeQuestion question) {
|
|
314
|
+ List<MsrSubjectQuestionSection> rtnList = new ArrayList<>();
|
|
315
|
+ for (MsrSubjectQuestionSection section : sections) {
|
|
316
|
+ String[] userids = section.getFdids().split(",");
|
|
317
|
+ List<String> useridList = Arrays.asList(userids);
|
|
318
|
+ List<MsPaperStudentQuestion> sectionStuQuestions = stuQuestions.stream().filter(q -> useridList.contains(q.getStudentid().toString())).collect(Collectors.toList());
|
|
319
|
+ // 获取总分
|
|
320
|
+ double sumScore = sectionStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
|
|
321
|
+ int stuNum = sectionStuQuestions.size();
|
|
322
|
+ // 获取平均分
|
|
323
|
+ double avgScore = MarkingUtil.div(sumScore, stuNum);
|
|
324
|
+ // 获取平均得分率
|
|
325
|
+ double avgScoreRate = MarkingUtil.calculateRate(avgScore, question.getQscore());
|
|
326
|
+ section.setAvgscore(avgScore);
|
|
327
|
+ section.setAvgrate(avgScoreRate);
|
|
328
|
+ section.setQntype(1);
|
|
329
|
+ section.setMptqid(question.getMptqid());
|
|
330
|
+ rtnList.add(section);
|
277
|
331
|
}
|
|
332
|
+ return rtnList;
|
278
|
333
|
}
|
|
334
|
+
|
|
335
|
+ // 题型分析
|
|
336
|
+ private void handleQtype(List<MsPaperStudentQuestion> subjectStuQuestions,List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
|
|
337
|
+ List<MsrReportparam> params,Integer examid, String subjectid) {
|
|
338
|
+ List<MsrClassQtype> saveQtypes = new ArrayList<>();//班级题型分析
|
|
339
|
+ // 处理大题
|
|
340
|
+ Map<Integer, List<MsPaperQtypeQuestion>> qtypeMap = questions.stream().collect(Collectors.groupingBy(MsPaperQtypeQuestion::getMptid));
|
|
341
|
+ for (Map.Entry<Integer, List<MsPaperQtypeQuestion>> entry : qtypeMap.entrySet()) {
|
|
342
|
+ List<MsPaperQtypeQuestion> qtypeQuestions = entry.getValue();
|
|
343
|
+ Double fullScore = qtypeQuestions.stream().mapToDouble(MsPaperQtypeQuestion::getQscore).sum();// 题型满分
|
|
344
|
+
|
|
345
|
+ // 获取所有题型下试题id集合
|
|
346
|
+ List<Integer> mptqids = qtypeQuestions.stream().map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
|
|
347
|
+ // 获取题型下所有学生试题情况
|
|
348
|
+ List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
|
|
349
|
+ //初始化信息
|
|
350
|
+ MsrClassQtype schoolQtype = new MsrClassQtype();
|
|
351
|
+ schoolQtype.setExamid(examid);
|
|
352
|
+ schoolQtype.setSubjectid(subjectid);
|
|
353
|
+ schoolQtype.setClassid(0);
|
|
354
|
+ schoolQtype.setMptid(entry.getKey());
|
|
355
|
+ schoolQtype.setMptqn(qtypeQuestions.get(0).getMptqn());
|
|
356
|
+ schoolQtype.setFullscore(fullScore);
|
|
357
|
+
|
|
358
|
+ //全校班级题型情况
|
|
359
|
+ MsrClassQtype qtypeSchool = qtypeClass(stuQuestions, params, schoolQtype);
|
|
360
|
+ saveQtypes.add(qtypeSchool);
|
|
361
|
+
|
|
362
|
+ // 班级题型分析
|
|
363
|
+ // 获取所有班级
|
|
364
|
+ List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
|
|
365
|
+ for (Integer classid : classIds) {
|
|
366
|
+ schoolQtype.setClassid(classid);
|
|
367
|
+ // 获取班级下学生id
|
|
368
|
+ List<Integer> classStuIds =
|
|
369
|
+ subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
|
|
370
|
+ // 获取班级下学生试题
|
|
371
|
+ List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
|
|
372
|
+ // 班级题型分析
|
|
373
|
+ MsrClassQtype qtypeClass = qtypeClass(classStuQuestions, params, schoolQtype);
|
|
374
|
+ saveQtypes.add(qtypeClass);
|
|
375
|
+ }
|
|
376
|
+ }
|
|
377
|
+ }
|
|
378
|
+ // 题型分析-学校、班级分析
|
|
379
|
+ private MsrClassQtype qtypeClass(List<MsPaperStudentQuestion> stuQuestions, List<MsrReportparam> params,MsrClassQtype schoolQtype){
|
|
380
|
+ // 获取所有学生id
|
|
381
|
+ List<Integer> studentIds = stuQuestions.stream().map(MsPaperStudentQuestion::getStudentid).distinct().collect(Collectors.toList());
|
|
382
|
+ int stuNum = stuQuestions.size();
|
|
383
|
+ List<Double> stuScores = new ArrayList<>();
|
|
384
|
+ int mfnum = 0;
|
|
385
|
+ String mfids = "";
|
|
386
|
+ int lfnum = 0;
|
|
387
|
+ String lfids = "";
|
|
388
|
+ for (Integer studentId : studentIds) {
|
|
389
|
+ List<MsPaperStudentQuestion> stuQtype = stuQuestions.stream().filter(q -> studentId.equals(q.getMptqid())).collect(Collectors.toList());
|
|
390
|
+ Double stuQtypeScore = stuQtype.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
|
|
391
|
+ stuScores.add(stuQtypeScore);
|
|
392
|
+ if(schoolQtype.getFullscore() == stuQtypeScore){
|
|
393
|
+ mfnum++;
|
|
394
|
+ mfids += studentId + ",";
|
|
395
|
+ }else{
|
|
396
|
+ lfnum++;
|
|
397
|
+ lfids += studentId + ",";
|
|
398
|
+ }
|
|
399
|
+ }
|
|
400
|
+
|
|
401
|
+ Double stuSumScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 学生总分
|
|
402
|
+ Double avgScore = MarkingUtil.div(stuSumScore, stuNum);// 平均分
|
|
403
|
+
|
|
404
|
+ MsrClassQtype classQtype = new MsrClassQtype();
|
|
405
|
+ classQtype.setExamid(schoolQtype.getExamid());
|
|
406
|
+ classQtype.setSubjectid(schoolQtype.getSubjectid());
|
|
407
|
+ classQtype.setClassid(schoolQtype.getClassid());
|
|
408
|
+ classQtype.setMptid(schoolQtype.getMptid());
|
|
409
|
+ classQtype.setMptqn(schoolQtype.getMptqn());
|
|
410
|
+ classQtype.setFullscore(schoolQtype.getFullscore());
|
|
411
|
+ classQtype.setAvgscore(avgScore);
|
|
412
|
+ classQtype.setBzc(MarkingUtil.bzc(stuScores));
|
|
413
|
+ classQtype.setNd(MarkingUtil.div(avgScore, schoolQtype.getFullscore()));
|
|
414
|
+ classQtype.setNdms(questionNdAndQfd(params, 1, schoolQtype.getNd())[0]);
|
|
415
|
+ classQtype.setQfd(MarkingUtil.qfd(stuScores));
|
|
416
|
+ classQtype.setQfdms(questionNdAndQfd(params, 2, schoolQtype.getQfd())[0]);
|
|
417
|
+ classQtype.setMfnum(mfnum);
|
|
418
|
+ classQtype.setMfrate(MarkingUtil.div(mfnum, stuNum));
|
|
419
|
+ if(mfnum > 0){
|
|
420
|
+ schoolQtype.setMfids(mfids.substring(0,mfids.length()-1));
|
|
421
|
+ }
|
|
422
|
+ classQtype.setMfids(mfids);
|
|
423
|
+ classQtype.setLfnum(lfnum);
|
|
424
|
+ classQtype.setLfrate(MarkingUtil.div(lfnum, stuNum));
|
|
425
|
+ if(lfnum > 0){
|
|
426
|
+ classQtype.setMfids(lfids.substring(0,lfids.length()-1));
|
|
427
|
+ }
|
|
428
|
+
|
|
429
|
+ return classQtype;
|
|
430
|
+ }
|
|
431
|
+
|
279
|
432
|
}
|