|
|
@@ -0,0 +1,361 @@
|
|
|
+package com.seecoder.dataanalysis.analysis.impl;
|
|
|
+
|
|
|
+import com.seecoder.dataanalysis.analysis.DevcloudDataAnalysisService;
|
|
|
+import com.seecoder.dataanalysis.analysis.DevcloudScoreService;
|
|
|
+import com.seecoder.dataanalysis.analysis.DisplayService;
|
|
|
+import com.seecoder.dataanalysis.data.entity.devcloud.display.Contribution;
|
|
|
+import com.seecoder.dataanalysis.data.entity.devcloud.display.FormatGroup;
|
|
|
+import com.seecoder.dataanalysis.data.entity.devcloud.display.FormatScore;
|
|
|
+import com.seecoder.dataanalysis.data.entity.devcloud.display.FormatStudent;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class DevcloudScoreServiceImpl implements DevcloudScoreService {
|
|
|
+ @Autowired
|
|
|
+ private DevcloudDataAnalysisService devcloudDataAnalysisService;
|
|
|
+ @Autowired
|
|
|
+ private DisplayService displayService;
|
|
|
+
|
|
|
+ public static final int A = 80;
|
|
|
+ public static final int B = 100;
|
|
|
+
|
|
|
+ public static final int COMMIT_TIME = 80;
|
|
|
+ public static final int COMMIT_TIME_PER = 20;
|
|
|
+ public static final double COMMIT_VALID_RATE = 0.6;
|
|
|
+ public static final int BUG_TIME = 8;
|
|
|
+ public static final int BUG_TIME_PER = 2;
|
|
|
+ public static final double BUG_FINISHED_RATE = 0.9;
|
|
|
+ public static final int NODE_TIME = 50;
|
|
|
+ public static final int NODE_TIME_PER = 12;
|
|
|
+ public static final double NODE_FINISHED_RATE = 0.5;
|
|
|
+ public static final int PIPELINE_TIME = 12;
|
|
|
+ public static final int PIPELINE_TIME_PER = 3;
|
|
|
+ public static final double PIPELINE_SUCCESS_RATE = 0.9;
|
|
|
+
|
|
|
+ public FormatScore getGroupScore(int user_id){
|
|
|
+ FormatScore formatScore = new FormatScore();
|
|
|
+ FormatGroup formatGroup = displayService.getGroupAnalysisById(user_id);
|
|
|
+ //commit
|
|
|
+ int commit_times = formatGroup.getCommit().getCommit_times();
|
|
|
+ int commit_valid_times = formatGroup.getCommit().getValid_commit_times();
|
|
|
+ double commit_valid_rate = (double) commit_valid_times/(double) commit_times;
|
|
|
+ double commitScore1 = 0.0,commitScore2 = 0.0,commitScore=0.0;
|
|
|
+ if(commit_times>=COMMIT_TIME){
|
|
|
+ commitScore1 = 100;
|
|
|
+ }else {
|
|
|
+ commitScore1 = commit_times/COMMIT_TIME * 100;
|
|
|
+ }
|
|
|
+ if(commit_valid_rate>=COMMIT_VALID_RATE){
|
|
|
+ commitScore2 = 100;
|
|
|
+ }else {
|
|
|
+ commitScore2 = commit_valid_rate/COMMIT_VALID_RATE * 100;
|
|
|
+ }
|
|
|
+ commitScore = (commitScore1+commitScore2)/2;
|
|
|
+ formatScore.setCommitScore(commitScore);
|
|
|
+
|
|
|
+ //bugList
|
|
|
+ int bug_times = formatGroup.getBuglist().getBug_times();
|
|
|
+ int bug_finished_times = formatGroup.getBuglist().getFinished_times();
|
|
|
+ double bug_finished_rate = (double)bug_finished_times/(double)bug_times;
|
|
|
+ double bugScore1=0.0,bugScore2=0.0,bugScore=0.0;
|
|
|
+ if(bug_times>=BUG_TIME){
|
|
|
+ bugScore1 = 100;
|
|
|
+ }else {
|
|
|
+ bugScore1 = bug_times/BUG_TIME * 100;
|
|
|
+ }
|
|
|
+ if(bug_finished_rate>=BUG_FINISHED_RATE){
|
|
|
+ bugScore2 = 100;
|
|
|
+ }else {
|
|
|
+ bugScore2 = bug_finished_rate/BUG_FINISHED_RATE * 100;
|
|
|
+ }
|
|
|
+ bugScore = (bugScore1+bugScore2)/2;
|
|
|
+ formatScore.setBugScore(bugScore);
|
|
|
+
|
|
|
+ //nodeList
|
|
|
+ int treeNode_times = formatGroup.getTreeNode().getTreeNode_times();
|
|
|
+ int treeNode_finished_times = formatGroup.getTreeNode().getFinished_treeNode_times();
|
|
|
+ double treeNode_finished_rate = (double) treeNode_finished_times/ (double) treeNode_times;
|
|
|
+ double nodeScore1=0.0,nodeScore2=0.0,nodeScore=0.0;
|
|
|
+ if(treeNode_times>=NODE_TIME){
|
|
|
+ nodeScore1 = 100;
|
|
|
+ }else {
|
|
|
+ nodeScore1 = treeNode_times/NODE_TIME * 100;
|
|
|
+ }
|
|
|
+ if(treeNode_finished_rate>=NODE_FINISHED_RATE){
|
|
|
+ nodeScore2 = 100;
|
|
|
+ }else {
|
|
|
+ nodeScore2 = treeNode_finished_rate/NODE_FINISHED_RATE * 100;
|
|
|
+ }
|
|
|
+ nodeScore = (nodeScore1+nodeScore2)/2;
|
|
|
+ formatScore.setNodeScore(nodeScore);
|
|
|
+
|
|
|
+ //pipeline
|
|
|
+ int pipeline_times = formatGroup.getPipeline().getPipeline_deploy();
|
|
|
+ int pipeline_success_times = formatGroup.getPipeline().getPipeline_pass();
|
|
|
+ double pipeline_success_rate = (double)pipeline_success_times/(double)pipeline_times;
|
|
|
+ double pipelineScore1=0.0,pipelineScore2=0.0,pipelineScore=0.0;
|
|
|
+ if(pipeline_times>=PIPELINE_TIME){
|
|
|
+ pipelineScore1 = 100;
|
|
|
+ }else {
|
|
|
+ pipelineScore1 = pipeline_times/PIPELINE_TIME * 100;
|
|
|
+ }
|
|
|
+ if(pipeline_success_rate>=PIPELINE_SUCCESS_RATE){
|
|
|
+ pipelineScore2 = 100;
|
|
|
+ }else {
|
|
|
+ pipelineScore2 = pipeline_success_rate/PIPELINE_SUCCESS_RATE * 100;
|
|
|
+ }
|
|
|
+ pipelineScore = (nodeScore1+nodeScore2)/2;
|
|
|
+ formatScore.setPipelineScore(pipelineScore);
|
|
|
+
|
|
|
+ //bonus,根据学生的分数占比计算
|
|
|
+ List<Contribution> commitContribution = formatGroup.getCommit().getCommit_contribution();
|
|
|
+ int totalCommit = 0;
|
|
|
+ for(Contribution contribution:commitContribution){
|
|
|
+ totalCommit += contribution.getTimes();
|
|
|
+ }
|
|
|
+ double[] xCommit=new double[commitContribution.size()];
|
|
|
+ if(totalCommit!=0){
|
|
|
+ for(int i=0;i<commitContribution.size();i++){
|
|
|
+ xCommit[i] = commitContribution.get(i).getTimes()/totalCommit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Contribution> bugContribution = formatGroup.getBuglist().getBug_contribution();
|
|
|
+ int totalBug = 0;
|
|
|
+ for(Contribution contribution:bugContribution){
|
|
|
+ totalBug += contribution.getTimes();
|
|
|
+ }
|
|
|
+ double[] xBug=new double[bugContribution.size()];
|
|
|
+ if(totalBug!=0){
|
|
|
+ for(int i=0;i<bugContribution.size();i++){
|
|
|
+ xBug[i] = bugContribution.get(i).getTimes()/totalBug;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Contribution> nodeContribution = formatGroup.getTreeNode().getTreeNode_contribution();
|
|
|
+ int totalNode = 0;
|
|
|
+ for(Contribution contribution:nodeContribution){
|
|
|
+ totalNode += contribution.getTimes();
|
|
|
+ }
|
|
|
+ double[] xNode=new double[nodeContribution.size()];
|
|
|
+ if(totalNode!=0){
|
|
|
+ for(int i=0;i<nodeContribution.size();i++){
|
|
|
+ xNode[i] = nodeContribution.get(i).getTimes()/totalNode;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Contribution> pipeContribution = formatGroup.getPipeline().getPipeline_contribution();
|
|
|
+ int totalPipe = 0;
|
|
|
+ for(Contribution contribution:pipeContribution){
|
|
|
+ totalPipe += contribution.getTimes();
|
|
|
+ }
|
|
|
+ double[] xPipe=new double[pipeContribution.size()];
|
|
|
+ if(totalPipe!=0){
|
|
|
+ for(int i=0;i<pipeContribution.size();i++){
|
|
|
+ xPipe[i] = pipeContribution.get(i).getTimes()/totalPipe;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double s1=StandardDiviation(xCommit),s2=StandardDiviation(xBug),s3=StandardDiviation(xNode),s4=StandardDiviation(xPipe);
|
|
|
+ double s = 10 - (s1+s2+s3+s4)*10;
|
|
|
+
|
|
|
+ //计算基础四项总分
|
|
|
+ double preScore = Math.ceil((commitScore+bugScore+nodeScore+pipelineScore)/4);
|
|
|
+ double bonus = Math.ceil(s);
|
|
|
+
|
|
|
+ formatScore.setTotalScore(preScore+bonus);
|
|
|
+ formatScore.setBonus(bonus);
|
|
|
+
|
|
|
+ return formatScore;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public FormatScore getStudentScore(int user_id){
|
|
|
+ FormatScore formatScoreMain = getBasicScore(user_id);
|
|
|
+ Map<Integer,Double> totalScore = new HashMap<>();
|
|
|
+ List<Integer> userIds = new ArrayList<>();
|
|
|
+
|
|
|
+ //bonus,根据学生的分数占比计算
|
|
|
+ FormatGroup formatGroup = displayService.getGroupAnalysisById(user_id);
|
|
|
+ Map<Integer,Double> bonusScore = new HashMap<>();
|
|
|
+ List<Contribution> commitContribution = formatGroup.getCommit().getCommit_contribution();
|
|
|
+ List<Contribution> bugContribution = formatGroup.getBuglist().getBug_contribution();
|
|
|
+ List<Contribution> nodeContribution = formatGroup.getTreeNode().getTreeNode_contribution();
|
|
|
+ List<Contribution> pipeContribution = formatGroup.getPipeline().getPipeline_contribution();
|
|
|
+ for(Contribution contribution : commitContribution){
|
|
|
+ int id = contribution.getUserId();
|
|
|
+ userIds.add(id);
|
|
|
+ bonusScore.put(id,bonusScore.getOrDefault(id,0.0)+contribution.getProportion());
|
|
|
+ }
|
|
|
+ for(Contribution contribution : bugContribution){
|
|
|
+ int id = contribution.getUserId();
|
|
|
+ bonusScore.put(id,bonusScore.getOrDefault(id,0.0)+contribution.getProportion());
|
|
|
+ }
|
|
|
+ for(Contribution contribution : nodeContribution){
|
|
|
+ int id = contribution.getUserId();
|
|
|
+ bonusScore.put(id,bonusScore.getOrDefault(id,0.0)+contribution.getProportion());
|
|
|
+ }
|
|
|
+ for(Contribution contribution : pipeContribution){
|
|
|
+ int id = contribution.getUserId();
|
|
|
+ bonusScore.put(id,bonusScore.getOrDefault(id,0.0)+contribution.getProportion());
|
|
|
+ }
|
|
|
+ //遍历计算得到bonus的值
|
|
|
+ for(Map.Entry<Integer,Double> entry : bonusScore.entrySet()){
|
|
|
+ double value = entry.getValue();
|
|
|
+ value = value/4.0 - 0.25;
|
|
|
+ if(value < 0){
|
|
|
+ entry.setValue(0.0);
|
|
|
+ }else {
|
|
|
+ entry.setValue(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //使用targetIndex记录目标user_id的位置
|
|
|
+ int index=0,targetIndex=0;
|
|
|
+ double[] ori = new double[userIds.size()];
|
|
|
+ //计算基础四项总分
|
|
|
+ for(int userId : userIds){
|
|
|
+ FormatScore formatScore = getBasicScore(userId);
|
|
|
+ double total = 0.0;
|
|
|
+ total += formatScore.getCommitScore();
|
|
|
+ total += formatScore.getBugScore();
|
|
|
+ total += formatScore.getNodeScore();
|
|
|
+ total += formatScore.getPipelineScore();
|
|
|
+ total = Math.ceil(total/4.0);
|
|
|
+ total += Math.ceil(bonusScore.get(userId));
|
|
|
+ totalScore.put(userId,total);
|
|
|
+ ori[index] = total;
|
|
|
+ if(userId == user_id){
|
|
|
+ targetIndex = index;
|
|
|
+ }
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+
|
|
|
+ //将分数映射到A B上
|
|
|
+ double Xmin = 0.0,Xmax = 0.0;
|
|
|
+ for(int i=0;i<ori.length;i++){
|
|
|
+ double d = ori[i];
|
|
|
+ if(d<=Xmin){
|
|
|
+ Xmin = d;
|
|
|
+ }
|
|
|
+ if(d>=Xmax){
|
|
|
+ Xmax = d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(Xmin != Xmax){
|
|
|
+ for(int i=0;i<ori.length;i++){
|
|
|
+ ori[i] = A + (B-A) / (Xmax-Xmin) * (ori[i]-Xmin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ formatScoreMain.setTotalScore(ori[targetIndex]);
|
|
|
+ formatScoreMain.setBonus(bonusScore.get(user_id));
|
|
|
+
|
|
|
+ return formatScoreMain;
|
|
|
+ }
|
|
|
+
|
|
|
+ //根据学生id计算学生的基础得分
|
|
|
+ public FormatScore getBasicScore(int user_id){
|
|
|
+ FormatScore formatScore = new FormatScore();
|
|
|
+ FormatStudent formatStudent = devcloudDataAnalysisService.getStudentAnalysis(user_id);
|
|
|
+ //commit
|
|
|
+ int commit_times = formatStudent.getCommit().getCommit_times();
|
|
|
+ int commit_valid_times = formatStudent.getCommit().getValid_commit_times();
|
|
|
+ double commit_valid_rate = (double) commit_valid_times/(double) commit_times;
|
|
|
+ double commitScore1 = 0.0,commitScore2 = 0.0,commitScore=0.0;
|
|
|
+ if(commit_times>=COMMIT_TIME_PER){
|
|
|
+ commitScore1 = 100;
|
|
|
+ }else {
|
|
|
+ commitScore1 = commit_times/COMMIT_TIME_PER * 100;
|
|
|
+ }
|
|
|
+ if(commit_valid_rate>=COMMIT_VALID_RATE){
|
|
|
+ commitScore2 = 100;
|
|
|
+ }else {
|
|
|
+ commitScore2 = commit_valid_rate/COMMIT_VALID_RATE * 100;
|
|
|
+ }
|
|
|
+ commitScore = (commitScore1+commitScore2)/2;
|
|
|
+ formatScore.setCommitScore(commitScore);
|
|
|
+
|
|
|
+ //bugList
|
|
|
+ int bug_times = formatStudent.getBuglist().getBug_times();
|
|
|
+ int bug_finished_times = formatStudent.getBuglist().getFinished_times();
|
|
|
+ double bug_finished_rate = (double)bug_finished_times/(double)bug_times;
|
|
|
+ double bugScore1=0.0,bugScore2=0.0,bugScore=0.0;
|
|
|
+ if(bug_times>=BUG_TIME_PER){
|
|
|
+ bugScore1 = 100;
|
|
|
+ }else {
|
|
|
+ bugScore1 = bug_times/BUG_TIME_PER * 100;
|
|
|
+ }
|
|
|
+ if(bug_finished_rate>=BUG_FINISHED_RATE){
|
|
|
+ bugScore2 = 100;
|
|
|
+ }else {
|
|
|
+ bugScore2 = bug_finished_rate/BUG_FINISHED_RATE * 100;
|
|
|
+ }
|
|
|
+ bugScore = (bugScore1+bugScore2)/2;
|
|
|
+ formatScore.setBugScore(bugScore);
|
|
|
+
|
|
|
+ //nodeList
|
|
|
+ int treeNode_times = formatStudent.getTreeNode().getTreeNode_times();
|
|
|
+ int treeNode_finished_times = formatStudent.getTreeNode().getFinished_treeNode_times();
|
|
|
+ double treeNode_finished_rate = (double) treeNode_finished_times/ (double) treeNode_times;
|
|
|
+ double nodeScore1=0.0,nodeScore2=0.0,nodeScore=0.0;
|
|
|
+ if(treeNode_times>=NODE_TIME_PER){
|
|
|
+ nodeScore1 = 100;
|
|
|
+ }else {
|
|
|
+ nodeScore1 = treeNode_times/NODE_TIME_PER * 100;
|
|
|
+ }
|
|
|
+ if(treeNode_finished_rate>=NODE_FINISHED_RATE){
|
|
|
+ nodeScore2 = 100;
|
|
|
+ }else {
|
|
|
+ nodeScore2 = treeNode_finished_rate/NODE_FINISHED_RATE * 100;
|
|
|
+ }
|
|
|
+ nodeScore = (nodeScore1+nodeScore2)/2;
|
|
|
+ formatScore.setNodeScore(nodeScore);
|
|
|
+
|
|
|
+ //pipeline
|
|
|
+ int pipeline_times = formatStudent.getPipeline().getPipeline_deploy();
|
|
|
+ int pipeline_success_times = formatStudent.getPipeline().getPipeline_pass();
|
|
|
+ double pipeline_success_rate = (double)pipeline_success_times/(double)pipeline_times;
|
|
|
+ double pipelineScore1=0.0,pipelineScore2=0.0,pipelineScore=0.0;
|
|
|
+ if(pipeline_times>=PIPELINE_TIME_PER){
|
|
|
+ pipelineScore1 = 100;
|
|
|
+ }else {
|
|
|
+ pipelineScore1 = pipeline_times/PIPELINE_TIME_PER * 100;
|
|
|
+ }
|
|
|
+ if(pipeline_success_rate>=PIPELINE_SUCCESS_RATE){
|
|
|
+ pipelineScore2 = 100;
|
|
|
+ }else {
|
|
|
+ pipelineScore2 = pipeline_success_rate/PIPELINE_SUCCESS_RATE * 100;
|
|
|
+ }
|
|
|
+ pipelineScore = (nodeScore1+nodeScore2)/2;
|
|
|
+ formatScore.setPipelineScore(pipelineScore);
|
|
|
+
|
|
|
+ return formatScore;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //标准差σ=sqrt(s^2)
|
|
|
+ public static double StandardDiviation(double[] x) {
|
|
|
+ int m=x.length;
|
|
|
+ double sum=0;
|
|
|
+ for(int i=0;i<m;i++){//求和
|
|
|
+ sum+=x[i];
|
|
|
+ }
|
|
|
+ double dAve=sum/m;//求平均值
|
|
|
+ double dVar=0;
|
|
|
+ for(int i=0;i<m;i++){//求方差
|
|
|
+ dVar+=(x[i]-dAve)*(x[i]-dAve);
|
|
|
+ }
|
|
|
+ return Math.sqrt(dVar/(m-1));
|
|
|
+// return Math.sqrt(dVar/m);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|