Commit 94e3820a144a05569b04ff4df200c30b5ba0e866
1 parent
a923e3fe
Exists in
master
四维诊断
Showing
6 changed files
with
100 additions
and
32 deletions
Show diff stats
src/main/java/com/jevon/controller/LearnController.java
@@ -173,8 +173,9 @@ public class LearnController { | @@ -173,8 +173,9 @@ public class LearnController { | ||
173 | int dimensionalId = 0 ; | 173 | int dimensionalId = 0 ; |
174 | if(result == null || result.getId() == 0){ | 174 | if(result == null || result.getId() == 0){ |
175 | dimensional.setCreateTime(new Date()); | 175 | dimensional.setCreateTime(new Date()); |
176 | - dimensionalId = dimensionalService.insert(dimensional); | ||
177 | - }else { | 176 | + dimensionalService.insert(dimensional); |
177 | + dimensionalId = dimensional.getId(); | ||
178 | + }else{ | ||
178 | dimensionalId = result.getId(); | 179 | dimensionalId = result.getId(); |
179 | } | 180 | } |
180 | AnalyseDimensional analyseDimensional = new AnalyseDimensional(); | 181 | AnalyseDimensional analyseDimensional = new AnalyseDimensional(); |
@@ -200,6 +201,11 @@ public class LearnController { | @@ -200,6 +201,11 @@ public class LearnController { | ||
200 | private void analysisScoreExcel(InitAnalyseReqVo initAnalyseReqVo){ | 201 | private void analysisScoreExcel(InitAnalyseReqVo initAnalyseReqVo){ |
201 | try{ | 202 | try{ |
202 | Analyse analyse = analyseService.selectById(initAnalyseReqVo.getAnalyseId()); | 203 | Analyse analyse = analyseService.selectById(initAnalyseReqVo.getAnalyseId()); |
204 | + List<AnalyseDetail> analyseDetails = analyseDetailService.selectByAnalyseId(analyse.getId()); | ||
205 | + Map<String , Double> scoreMap = new HashMap<>(); | ||
206 | + for(AnalyseDetail analyseDetail : analyseDetails){ | ||
207 | + scoreMap.put(analyseDetail.getQuestionNumber(),analyseDetail.getScore()); | ||
208 | + } | ||
203 | String fileUrl = initAnalyseReqVo.getUrl(); | 209 | String fileUrl = initAnalyseReqVo.getUrl(); |
204 | File excelFile = new File(fileUrl); | 210 | File excelFile = new File(fileUrl); |
205 | // 获得工作簿 | 211 | // 获得工作簿 |
@@ -218,6 +224,7 @@ public class LearnController { | @@ -218,6 +224,7 @@ public class LearnController { | ||
218 | Date date = new Date(); | 224 | Date date = new Date(); |
219 | int rows = sheet.getPhysicalNumberOfRows(); | 225 | int rows = sheet.getPhysicalNumberOfRows(); |
220 | Map<Integer , String> map = new HashMap<>(); | 226 | Map<Integer , String> map = new HashMap<>(); |
227 | + int column = 0 ; | ||
221 | for (int i = 0; i < rows; i++) { | 228 | for (int i = 0; i < rows; i++) { |
222 | // 获取第i行数据 | 229 | // 获取第i行数据 |
223 | Row sheetRow = sheet.getRow(i); | 230 | Row sheetRow = sheet.getRow(i); |
@@ -232,6 +239,7 @@ public class LearnController { | @@ -232,6 +239,7 @@ public class LearnController { | ||
232 | map.put(j,cell.getStringCellValue().trim()); | 239 | map.put(j,cell.getStringCellValue().trim()); |
233 | j++; | 240 | j++; |
234 | } | 241 | } |
242 | + column = j ; | ||
235 | } else { | 243 | } else { |
236 | ScoreExcelVo scoreExcelVo = new ScoreExcelVo(sheetRow); | 244 | ScoreExcelVo scoreExcelVo = new ScoreExcelVo(sheetRow); |
237 | if(StringUtils.isNotBlank(scoreExcelVo.getStudentName())){ | 245 | if(StringUtils.isNotBlank(scoreExcelVo.getStudentName())){ |
@@ -239,16 +247,21 @@ public class LearnController { | @@ -239,16 +247,21 @@ public class LearnController { | ||
239 | student.setAnalyseId(analyse.getId()); | 247 | student.setAnalyseId(analyse.getId()); |
240 | student.setCreateTime(date); | 248 | student.setCreateTime(date); |
241 | students.add(student); | 249 | students.add(student); |
242 | - int j = 7 ; | ||
243 | - while (sheetRow.getCell(j) != null){ | 250 | + for(int j = 7 ; j < column ; j++){ |
244 | Cell cell = sheetRow.getCell(j); | 251 | Cell cell = sheetRow.getCell(j); |
245 | StudentDetail studentDetail = new StudentDetail(scoreExcelVo); | 252 | StudentDetail studentDetail = new StudentDetail(scoreExcelVo); |
246 | studentDetail.setAnalyseId(analyse.getId()); | 253 | studentDetail.setAnalyseId(analyse.getId()); |
247 | studentDetail.setExamNumber(map.get(j)); | 254 | studentDetail.setExamNumber(map.get(j)); |
248 | studentDetail.setScore(new Double(cell.getNumericCellValue())); | 255 | studentDetail.setScore(new Double(cell.getNumericCellValue())); |
256 | + Double score = scoreMap.get((map.get(j))) ; | ||
257 | + Double studentScore = studentDetail.getScore() ; | ||
258 | + if(Double.doubleToLongBits(score) == Double.doubleToLongBits(studentScore) ){ | ||
259 | + studentDetail.setCorrect(1); | ||
260 | + }else { | ||
261 | + studentDetail.setCorrect(0); | ||
262 | + } | ||
249 | studentDetail.setCreateTime(date); | 263 | studentDetail.setCreateTime(date); |
250 | studentDetails.add(studentDetail); | 264 | studentDetails.add(studentDetail); |
251 | - j++; | ||
252 | } | 265 | } |
253 | } | 266 | } |
254 | } | 267 | } |
src/main/java/com/jevon/controller/LearnStatController.java
@@ -453,14 +453,14 @@ public class LearnStatController { | @@ -453,14 +453,14 @@ public class LearnStatController { | ||
453 | from5.setLeagueAvg(leagueSumScore / new Double(leagueStudents.size())); | 453 | from5.setLeagueAvg(leagueSumScore / new Double(leagueStudents.size())); |
454 | from5.setSchoolAvg(schoolSumScore / new Double(students.size())); | 454 | from5.setSchoolAvg(schoolSumScore / new Double(students.size())); |
455 | 455 | ||
456 | - int allHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDetail.getQuestionNumber(),allHighStudent,analyseDetail.getScore()); | ||
457 | - int allLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDetail.getQuestionNumber(),allLowStudent,analyseDetail.getScore()); | 456 | + int allHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDetail.getQuestionNumber(),allHighStudent); |
457 | + int allLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDetail.getQuestionNumber(),allLowStudent); | ||
458 | 458 | ||
459 | - int leagueHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDetail.getQuestionNumber(),allHighStudent,analyseDetail.getScore()); | ||
460 | - int leagueLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDetail.getQuestionNumber(),allLowStudent,analyseDetail.getScore()); | 459 | + int leagueHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDetail.getQuestionNumber(),allHighStudent); |
460 | + int leagueLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDetail.getQuestionNumber(),allLowStudent); | ||
461 | 461 | ||
462 | - int high = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDetail.getQuestionNumber(),highStudent,analyseDetail.getScore()); | ||
463 | - int low = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDetail.getQuestionNumber(),lowStudent,analyseDetail.getScore()); | 462 | + int high = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDetail.getQuestionNumber(),highStudent); |
463 | + int low = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDetail.getQuestionNumber(),lowStudent); | ||
464 | from5.setAllDist(new Double(allHigh-allLow)/new Double(allNumber)); | 464 | from5.setAllDist(new Double(allHigh-allLow)/new Double(allNumber)); |
465 | from5.setLeagueDist(new Double(leagueHigh-leagueLow)/new Double(leagueNumber)); | 465 | from5.setLeagueDist(new Double(leagueHigh-leagueLow)/new Double(leagueNumber)); |
466 | from5.setSchoolDist(new Double(high-low)/new Double(number)); | 466 | from5.setSchoolDist(new Double(high-low)/new Double(number)); |
@@ -597,24 +597,25 @@ public class LearnStatController { | @@ -597,24 +597,25 @@ public class LearnStatController { | ||
597 | form6.setDimensional(dimensional.getDimensionalName()); | 597 | form6.setDimensional(dimensional.getDimensionalName()); |
598 | List<AnalyseDimensional> analyseDimensionals = analyseDimensionalService.selectByDimensional(analyse.getId(),dimensional.getId()); | 598 | List<AnalyseDimensional> analyseDimensionals = analyseDimensionalService.selectByDimensional(analyse.getId(),dimensional.getId()); |
599 | Double score = 0d; | 599 | Double score = 0d; |
600 | - Double allSumScore = 0d , leagueSumScore = 0d , schoolSumScore = 0d ; | ||
601 | - int allHigh = 0 , allLow = 0 , leagueHigh = 0 , leagueLow = 0 , high = 0 , low = 0 ; | ||
602 | StringBuffer examNumber = new StringBuffer(); | 600 | StringBuffer examNumber = new StringBuffer(); |
601 | + List<String> examNumberList = new ArrayList<>(); | ||
603 | for(AnalyseDimensional analyseDimensional :analyseDimensionals){ | 602 | for(AnalyseDimensional analyseDimensional :analyseDimensionals){ |
604 | score = score + analyseDimensional.getScore() ; | 603 | score = score + analyseDimensional.getScore() ; |
605 | - allSumScore = allSumScore + studentDetailService.selectSumScore(analyse.getId(),null,null,analyseDimensional.getQuestionNumber()); | ||
606 | - allHigh = allHigh + studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDimensional.getQuestionNumber(),allHighStudent,analyseDimensional.getScore()); | ||
607 | - allLow = allLow + studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,analyseDimensional.getQuestionNumber(),allLowStudent,analyseDimensional.getScore()); | ||
608 | - | ||
609 | - leagueSumScore = leagueSumScore + studentDetailService.selectSumScore(analyse.getId(),leagues,null,analyseDimensional.getQuestionNumber()); | ||
610 | - leagueHigh = leagueHigh + studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDimensional.getQuestionNumber(),allHighStudent,analyseDimensional.getScore()); | ||
611 | - leagueLow = leagueLow + studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,analyseDimensional.getQuestionNumber(),allLowStudent,analyseDimensional.getScore()); | ||
612 | - | ||
613 | - schoolSumScore = schoolSumScore + studentDetailService.selectSumScore(analyse.getId(),null,getLearnReqVo.getSchoolName(),analyseDimensional.getQuestionNumber()); | ||
614 | - high = high + studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDimensional.getQuestionNumber(),highStudent,analyseDimensional.getScore()); | ||
615 | - low = low + studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,analyseDimensional.getQuestionNumber(),lowStudent,analyseDimensional.getScore()); | ||
616 | examNumber.append(analyseDimensional.getQuestionNumber()).append(","); | 604 | examNumber.append(analyseDimensional.getQuestionNumber()).append(","); |
605 | + examNumberList.add(analyseDimensional.getQuestionNumber()); | ||
617 | } | 606 | } |
607 | + Double allSumScore = studentDetailService.selectSumScore(analyse.getId(),null,null,examNumberList); | ||
608 | + int allHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,examNumberList,allHighStudent); | ||
609 | + int allLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,null ,examNumberList,allLowStudent); | ||
610 | + | ||
611 | + Double leagueSumScore = studentDetailService.selectSumScore(analyse.getId(),leagues,null,examNumberList); | ||
612 | + int leagueHigh = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,examNumberList,allHighStudent); | ||
613 | + int leagueLow = studentDetailService.selectTrueByExamNumber(analyse.getId(),leagues,null ,examNumberList,allLowStudent); | ||
614 | + | ||
615 | + Double schoolSumScore = studentDetailService.selectSumScore(analyse.getId(),null,getLearnReqVo.getSchoolName(),examNumberList); | ||
616 | + int high = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,examNumberList,highStudent); | ||
617 | + int low = studentDetailService.selectTrueByExamNumber(analyse.getId(),null,getLearnReqVo.getSchoolName() ,examNumberList,lowStudent); | ||
618 | + | ||
618 | form6.setScore(score); | 619 | form6.setScore(score); |
619 | form6.setAllRate(allSumScore / new Double(allStudents.size()) / score ); | 620 | form6.setAllRate(allSumScore / new Double(allStudents.size()) / score ); |
620 | form6.setLeagueRate(leagueSumScore / new Double(leagueStudents.size()) / score ); | 621 | form6.setLeagueRate(leagueSumScore / new Double(leagueStudents.size()) / score ); |
src/main/java/com/jevon/model/StudentDetail.java
@@ -22,10 +22,12 @@ public class StudentDetail { | @@ -22,10 +22,12 @@ public class StudentDetail { | ||
22 | private String examNumber ; | 22 | private String examNumber ; |
23 | private Double score ; | 23 | private Double score ; |
24 | private Date createTime ; | 24 | private Date createTime ; |
25 | + private int correct ; //1 正确 0 错误 | ||
25 | 26 | ||
26 | //查询用 高分段 低分段学生考号 | 27 | //查询用 高分段 低分段学生考号 |
27 | private List<String> studentNumbers ; | 28 | private List<String> studentNumbers ; |
28 | private List<String> schoolNames ; | 29 | private List<String> schoolNames ; |
30 | + private List<String> examNumbers ; | ||
29 | 31 | ||
30 | public StudentDetail(ScoreExcelVo scoreExcelVo) { | 32 | public StudentDetail(ScoreExcelVo scoreExcelVo) { |
31 | this.schoolName = scoreExcelVo.getSchoolName(); | 33 | this.schoolName = scoreExcelVo.getSchoolName(); |
@@ -132,4 +134,20 @@ public class StudentDetail { | @@ -132,4 +134,20 @@ public class StudentDetail { | ||
132 | public void setSchoolNames(List<String> schoolNames) { | 134 | public void setSchoolNames(List<String> schoolNames) { |
133 | this.schoolNames = schoolNames; | 135 | this.schoolNames = schoolNames; |
134 | } | 136 | } |
137 | + | ||
138 | + public List<String> getExamNumbers() { | ||
139 | + return examNumbers; | ||
140 | + } | ||
141 | + | ||
142 | + public void setExamNumbers(List<String> examNumbers) { | ||
143 | + this.examNumbers = examNumbers; | ||
144 | + } | ||
145 | + | ||
146 | + public int getCorrect() { | ||
147 | + return correct; | ||
148 | + } | ||
149 | + | ||
150 | + public void setCorrect(int correct) { | ||
151 | + this.correct = correct; | ||
152 | + } | ||
135 | } | 153 | } |
src/main/java/com/jevon/service/StudentDetailService.java
@@ -15,5 +15,10 @@ public interface StudentDetailService { | @@ -15,5 +15,10 @@ public interface StudentDetailService { | ||
15 | 15 | ||
16 | Double selectSumScore(int analyseId, List<String> league , String schoolName, String examNumber); | 16 | Double selectSumScore(int analyseId, List<String> league , String schoolName, String examNumber); |
17 | 17 | ||
18 | - int selectTrueByExamNumber(int analyseId , List<String> league , String schoolName , String examNumber , List<String> studentNumbers ,Double score); | 18 | + Double selectSumScore(int analyseId, List<String> league , String schoolName, List<String> examNumbers); |
19 | + | ||
20 | + int selectTrueByExamNumber(int analyseId , List<String> league , String schoolName , String examNumber , List<String> studentNumbers); | ||
21 | + | ||
22 | + int selectTrueByExamNumber(int analyseId , List<String> league , String schoolName , List<String> examNumbers , List<String> studentNumbers); | ||
23 | + | ||
19 | } | 24 | } |
src/main/java/com/jevon/service/impl/StudentDetailServiceImpl.java
@@ -47,12 +47,32 @@ public class StudentDetailServiceImpl implements StudentDetailService { | @@ -47,12 +47,32 @@ public class StudentDetailServiceImpl implements StudentDetailService { | ||
47 | } | 47 | } |
48 | 48 | ||
49 | @Override | 49 | @Override |
50 | - public int selectTrueByExamNumber(int analyseId,List<String> league , String schoolName, String examNumber, List<String> studentNumbers , Double score) { | 50 | + public Double selectSumScore(int analyseId, List<String> league, String schoolName, List<String> examNumbers) { |
51 | + StudentDetail studentDetail = new StudentDetail(); | ||
52 | + studentDetail.setAnalyseId(analyseId); | ||
53 | + studentDetail.setSchoolName(schoolName); | ||
54 | + studentDetail.setExamNumbers(examNumbers); | ||
55 | + studentDetail.setSchoolNames(league); | ||
56 | + return studentDetailMapper.selectSumScore(studentDetail); | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public int selectTrueByExamNumber(int analyseId,List<String> league , String schoolName, String examNumber, List<String> studentNumbers) { | ||
51 | StudentDetail studentDetail = new StudentDetail(); | 61 | StudentDetail studentDetail = new StudentDetail(); |
52 | studentDetail.setAnalyseId(analyseId); | 62 | studentDetail.setAnalyseId(analyseId); |
53 | studentDetail.setSchoolName(schoolName); | 63 | studentDetail.setSchoolName(schoolName); |
54 | studentDetail.setExamNumber(examNumber); | 64 | studentDetail.setExamNumber(examNumber); |
55 | - studentDetail.setScore(score); | 65 | + studentDetail.setStudentNumbers(studentNumbers); |
66 | + studentDetail.setSchoolNames(league); | ||
67 | + return studentDetailMapper.selectTrueByExamNumber(studentDetail); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public int selectTrueByExamNumber(int analyseId, List<String> league, String schoolName, List<String> examNumbers, List<String> studentNumbers) { | ||
72 | + StudentDetail studentDetail = new StudentDetail(); | ||
73 | + studentDetail.setAnalyseId(analyseId); | ||
74 | + studentDetail.setSchoolName(schoolName); | ||
75 | + studentDetail.setExamNumbers(examNumbers); | ||
56 | studentDetail.setStudentNumbers(studentNumbers); | 76 | studentDetail.setStudentNumbers(studentNumbers); |
57 | studentDetail.setSchoolNames(league); | 77 | studentDetail.setSchoolNames(league); |
58 | return studentDetailMapper.selectTrueByExamNumber(studentDetail); | 78 | return studentDetailMapper.selectTrueByExamNumber(studentDetail); |
src/main/resources/mapping/StudentDetailMapper.xml
@@ -12,15 +12,16 @@ | @@ -12,15 +12,16 @@ | ||
12 | <result column="exam_number" property="examNumber" jdbcType="VARCHAR" /> | 12 | <result column="exam_number" property="examNumber" jdbcType="VARCHAR" /> |
13 | <result column="score" property="score" jdbcType="FLOAT" /> | 13 | <result column="score" property="score" jdbcType="FLOAT" /> |
14 | <result column="create_time" property="createTime" jdbcType="TIMESTAMP" /> | 14 | <result column="create_time" property="createTime" jdbcType="TIMESTAMP" /> |
15 | + <result column="correct" property="correct" jdbcType="INTEGER" /> | ||
15 | </resultMap> | 16 | </resultMap> |
16 | 17 | ||
17 | <insert id="insertBatch" parameterType="java.util.List"> | 18 | <insert id="insertBatch" parameterType="java.util.List"> |
18 | insert into sz_learn_student_detail (school_name, class_name,student_name, | 19 | insert into sz_learn_student_detail (school_name, class_name,student_name, |
19 | - student_number,analyse_id,exam_number,score,create_time) | 20 | + student_number,analyse_id,exam_number,score,create_time,correct) |
20 | values | 21 | values |
21 | <foreach collection="list" item="emp" separator=","> | 22 | <foreach collection="list" item="emp" separator=","> |
22 | (#{emp.schoolName},#{emp.className},#{emp.studentName}, | 23 | (#{emp.schoolName},#{emp.className},#{emp.studentName}, |
23 | - #{emp.studentNumber},#{emp.analyseId},#{emp.examNumber},#{emp.score},#{emp.createTime}) | 24 | + #{emp.studentNumber},#{emp.analyseId},#{emp.examNumber},#{emp.score},#{emp.createTime},#{emp.correct}) |
24 | </foreach> | 25 | </foreach> |
25 | </insert> | 26 | </insert> |
26 | 27 | ||
@@ -42,6 +43,12 @@ | @@ -42,6 +43,12 @@ | ||
42 | #{item} | 43 | #{item} |
43 | </foreach> | 44 | </foreach> |
44 | </if> | 45 | </if> |
46 | + <if test="examNumbers != null and examNumbers.size()>0"> | ||
47 | + AND exam_number IN | ||
48 | + <foreach item="item" index="index" collection="examNumbers" open="(" close=")" separator=","> | ||
49 | + #{item} | ||
50 | + </foreach> | ||
51 | + </if> | ||
45 | </where> | 52 | </where> |
46 | </select> | 53 | </select> |
47 | 54 | ||
@@ -57,9 +64,6 @@ | @@ -57,9 +64,6 @@ | ||
57 | <if test="examNumber != null"> | 64 | <if test="examNumber != null"> |
58 | and exam_number = #{examNumber} | 65 | and exam_number = #{examNumber} |
59 | </if> | 66 | </if> |
60 | - <if test="score != null"> | ||
61 | - and score = #{score} | ||
62 | - </if> | ||
63 | <if test="studentNumbers != null and studentNumbers.size()>0"> | 67 | <if test="studentNumbers != null and studentNumbers.size()>0"> |
64 | AND student_number IN | 68 | AND student_number IN |
65 | <foreach item="item" index="index" collection="studentNumbers" open="(" close=")" separator=","> | 69 | <foreach item="item" index="index" collection="studentNumbers" open="(" close=")" separator=","> |
@@ -72,7 +76,14 @@ | @@ -72,7 +76,14 @@ | ||
72 | #{item} | 76 | #{item} |
73 | </foreach> | 77 | </foreach> |
74 | </if> | 78 | </if> |
79 | + <if test="examNumbers != null and examNumbers.size()>0"> | ||
80 | + AND exam_number IN | ||
81 | + <foreach item="item" index="index" collection="examNumbers" open="(" close=")" separator=","> | ||
82 | + #{item} | ||
83 | + </foreach> | ||
84 | + </if> | ||
75 | </where> | 85 | </where> |
86 | + and correct = 1 | ||
76 | </select> | 87 | </select> |
77 | 88 | ||
78 | </mapper> | 89 | </mapper> |
79 | \ No newline at end of file | 90 | \ No newline at end of file |