Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

uncln 5 лет назад
Родитель
Сommit
8ed561ff95

+ 101 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/domain/CoderDao.java

@@ -0,0 +1,101 @@
+package cn.seecoder.data.server.domain;
+
+import lombok.Data;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+
+/**
+ * @author Sky
+ * */
+
+@Data
+@Entity
+@Table(name = "coder")
+public class CoderDao {
+
+    /**
+     * 本系统自增 id
+     * */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id" , nullable = false)
+    private Integer id;
+
+    /**
+     * 用户id
+     * */
+    @Column(name = "user_id" , nullable = false)
+    private Integer userId;
+
+    /**
+     * 考试id
+     * */
+    @Column(name = "exam_id" , nullable = false)
+    private Integer examId;
+
+    /**
+     * 对应coder系统的problem id
+     * */
+    @Column(name = "problem_id" , nullable = false)
+    private Integer problemId;
+
+    /**
+     * 对应coder系统的record id
+     * */
+    @Column(name = "record_id" , nullable = false)
+    private Integer recordId;
+
+    /**
+     * 本次考试的最后一次提交时间
+     * */
+    @Column(name = "last_commit_at" , nullable = false)
+    private LocalDateTime lastCommitAt;
+
+    /**
+     * 本条commit记录的id
+     * */
+    @Column(name = "commit_id", nullable = false)
+    private Integer commitId;
+
+    /**
+     * 本次提交时间
+     * */
+    @Column(name = "submit_at", nullable = false)
+    private LocalDateTime submitAt;
+
+    /**
+     * 本次题目得分
+     * */
+    @Column(name = "score", nullable = false)
+    private Integer score;
+
+    /**
+     * 考试开始时间
+     * */
+    @Column(name = "start_at", nullable = false)
+    private LocalDateTime startAt;
+
+    /**
+     * 考试结束时间
+     * */
+    @Column(name = "end_at", nullable = false)
+    private LocalDateTime endAt;
+
+    /**
+     * 在本系统的创建时间
+     * */
+    @CreationTimestamp
+    @Column(name = "created_at")
+    private LocalDateTime createdAt;
+
+    /**
+     * 在本系统的更新时间
+     * */
+    @UpdateTimestamp
+    @Column(name = "updated_at")
+    private LocalDateTime updatedAt;
+}

+ 16 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/repository/CoderRepository.java

@@ -0,0 +1,16 @@
+package cn.seecoder.data.server.repository;
+
+import cn.seecoder.data.server.domain.CoderDao;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface CoderRepository extends JpaRepository<CoderDao,Integer> {
+
+    List<CoderDao> findByUserId(Integer userId);
+
+    List<CoderDao> findByExamIdAndProblemIdOrderByLastCommitAt(Integer examId, Integer problemId);
+
+}

+ 5 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/service/CoderService.java

@@ -0,0 +1,5 @@
+package cn.seecoder.data.server.service;
+
+public interface CoderService {
+    public double getCoderGrade(Integer userId);
+}

+ 68 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/service/Impl/CoderServiceImpl.java

@@ -0,0 +1,68 @@
+package cn.seecoder.data.server.service.Impl;
+
+import cn.seecoder.data.server.domain.CoderDao;
+import cn.seecoder.data.server.repository.CoderRepository;
+import cn.seecoder.data.server.service.CoderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Service
+public class CoderServiceImpl implements CoderService {
+
+    @Autowired
+    CoderRepository coderRepository;
+
+    final double HEIGH = 1.05;
+    final double HEIGH_MIDDLE = 1.0;
+    final double MIDDLE_LOW = 0.95;
+    final double LOW = 0.85;
+
+    final double MAX_SCORE = 100;
+
+    @Override
+    public double getCoderGrade(Integer userId) {
+        AtomicReference<Double> grade = new AtomicReference<>(0.0);
+        AtomicReference<Double> sumGrade = new AtomicReference<>(0.0);
+        List<CoderDao> coderInfoByUser = coderRepository.findByUserId(userId);
+        coderInfoByUser.forEach(info -> {
+            double[] weight = new double[]{1.0, 1.0};
+            Integer score = info.getScore();
+            Integer problemId = info.getProblemId();
+            Integer examId = info.getExamId();
+            LocalDateTime lastCommitAt = info.getSubmitAt();
+            List<CoderDao> coderDaoList = coderRepository.findByExamIdAndProblemIdOrderByLastCommitAt(examId, problemId);
+
+            ArrayList<LocalDateTime> commitTimeQuartiles = new ArrayList<>(3);
+            commitTimeQuartiles.add(coderDaoList.get(coderDaoList.size()/4).getSubmitAt());
+            commitTimeQuartiles.add(coderDaoList.get(coderDaoList.size()*2/4).getSubmitAt());
+            commitTimeQuartiles.add(coderDaoList.get(coderDaoList.size()*3/4).getSubmitAt());
+            if(lastCommitAt.compareTo(commitTimeQuartiles.get(0))<=0) weight[0] = HEIGH;
+            else if(lastCommitAt.compareTo(commitTimeQuartiles.get(1))<=0) weight[0] = HEIGH_MIDDLE;
+            else if(lastCommitAt.compareTo(commitTimeQuartiles.get(2))<=0) weight[0] = MIDDLE_LOW;
+            else weight[0] = LOW;
+
+            Comparator<? super CoderDao> comparator = (Comparator<CoderDao>) (coderDao, t1) -> coderDao.getScore() - t1.getScore();
+            coderDaoList.sort(comparator);
+            ArrayList<Integer> scoreQuartiles = new ArrayList<>(3);
+            scoreQuartiles.add(coderDaoList.get(coderDaoList.size()/4).getScore());
+            scoreQuartiles.add(coderDaoList.get(coderDaoList.size()*2/4).getScore());
+            scoreQuartiles.add(coderDaoList.get(coderDaoList.size()*3/4).getScore());
+            if(score.compareTo(scoreQuartiles.get(0))<=0) weight[1] = HEIGH;
+            else if(score.compareTo(scoreQuartiles.get(1))<=0) weight[1] = HEIGH_MIDDLE;
+            else if(score.compareTo(scoreQuartiles.get(2))<=0) weight[1] = MIDDLE_LOW;
+            else weight[1] = LOW;
+
+            grade.updateAndGet(v -> v + weight[0] * weight[1] * score);
+            sumGrade.updateAndGet(v -> v + MAX_SCORE);
+        });
+
+        double result = grade.get() / sumGrade.get();
+        return Math.min(result, 1.0);
+    }
+}

+ 1 - 1
seec-data-server/src/main/resources/application.yml

@@ -2,7 +2,7 @@ spring:
   datasource:
     username: 'root'
     password: 'root'
-    url: jdbc:mysql://localhost:3306/seec_data?serverTimezone=GMT&useUnicode=true&characterEncoding=utf-8
+    url: jdbc:mysql://localhost:3306/seec_data?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8
     driver-class-name: com.mysql.cj.jdbc.Driver
   jpa:
     hibernate:

+ 44 - 0
seec-data-server/src/test/java/cn/seecoder/data/server/repository/CoderRepositoryTest.java

@@ -0,0 +1,44 @@
+package cn.seecoder.data.server.repository;
+
+import cn.seecoder.data.server.domain.CoderDao;
+import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class CoderRepositoryTest {
+
+    @Autowired
+    CoderRepository coderRepository;
+
+
+    @Test
+    public void testCoderRepo() {
+        Optional<CoderDao> coderRepositoryById = coderRepository.findById(1);
+        if(coderRepositoryById.isPresent()) {
+            CoderDao coderDao = coderRepositoryById.get();
+            System.out.println(coderDao);
+            coderDao.setUpdatedAt(null);
+            coderDao.setCreatedAt(LocalDateTime.now());
+            coderRepository.save(coderDao);
+            coderRepositoryById = coderRepository.findById(1);
+            if(coderRepositoryById.isPresent()) {
+                coderDao = coderRepositoryById.get();
+                System.out.println(coderDao);
+            }
+        }
+    }
+
+}

+ 36 - 0
seec-data-server/src/test/java/cn/seecoder/data/server/service/Impl/CoderServiceImplTest.java

@@ -0,0 +1,36 @@
+package cn.seecoder.data.server.service.Impl;
+
+import cn.seecoder.data.server.service.CoderService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@Rollback
+@SpringBootTest
+public class CoderServiceImplTest {
+    @Autowired
+    CoderService coderService;
+
+    @Test
+    public void testCoderGetGrade() {
+        System.out.println(coderService.getCoderGrade(999));
+        System.out.println(coderService.getCoderGrade(1000));
+        System.out.println(coderService.getCoderGrade(1001));
+        System.out.println(coderService.getCoderGrade(1002));
+        System.out.println(coderService.getCoderGrade(1003));
+        System.out.println(coderService.getCoderGrade(1004));
+    }
+}
+/**
+ * 0.7741363636363636
+ * 0.9625875
+ * 0.9299062499999999
+ * 0.575625
+ * 0.7781375
+ * 0.9810416666666667
+ * */