diff options
| author | Szymon Szukalski <szymon@skas.io> | 2024-07-23 23:23:45 +1000 |
|---|---|---|
| committer | Szymon Szukalski <szymon@skas.io> | 2024-07-23 23:23:45 +1000 |
| commit | f08b2fa7e6a977a18d6b9f14fb73c18ec73ec5df (patch) | |
| tree | 48ce214bc609130748b9630c2017000cafd29c2b /src/main/java/com/stileeducation/markr/service/TestResultsService.java | |
| parent | fa34f76ad8ebccb96012b45a4207532846cfa03f (diff) | |
Implement domain services
Implement core business logic for working with Student, Test, and TestResult.
Diffstat (limited to 'src/main/java/com/stileeducation/markr/service/TestResultsService.java')
| -rw-r--r-- | src/main/java/com/stileeducation/markr/service/TestResultsService.java | 148 |
1 files changed, 143 insertions, 5 deletions
diff --git a/src/main/java/com/stileeducation/markr/service/TestResultsService.java b/src/main/java/com/stileeducation/markr/service/TestResultsService.java index 2740e50..8d1b314 100644 --- a/src/main/java/com/stileeducation/markr/service/TestResultsService.java +++ b/src/main/java/com/stileeducation/markr/service/TestResultsService.java @@ -1,10 +1,148 @@ package com.stileeducation.markr.service; import com.stileeducation.markr.dto.AggregatedTestResultsDTO; -import com.stileeducation.markr.dto.MCQTestResultsDTO; +import com.stileeducation.markr.entity.Student; +import com.stileeducation.markr.entity.Test; +import com.stileeducation.markr.entity.TestResult; +import com.stileeducation.markr.repository.StudentRepository; +import com.stileeducation.markr.repository.TestRepository; +import com.stileeducation.markr.repository.TestResultRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; -public interface TestResultsService { - MCQTestResultsDTO importTestResults(MCQTestResultsDTO mcqTestResults); +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; - AggregatedTestResultsDTO aggregateTestResults(String testId); -} +@Service +public class TestResultsService { + + @Autowired + private TestResultRepository testResultRepository; + + @Autowired + private StudentRepository studentRepository; + + @Autowired + private TestRepository testRepository; + + public TestResult findOrCreateTestResult(Long studentId, Long testId, Integer marksAwarded) { + Student student = studentRepository.findById(studentId).orElseThrow(() -> new RuntimeException("Student not found")); + Test test = testRepository.findById(testId).orElseThrow(() -> new RuntimeException("Test not found")); + + Optional<TestResult> optionalTestResult = testResultRepository.findByStudentAndTest(student, test); + if (optionalTestResult.isPresent()) { + return optionalTestResult.get(); + } else { + TestResult testResult = new TestResult(); + testResult.setStudent(student); + testResult.setTest(test); + testResult.setMarksAwarded(marksAwarded); + return testResultRepository.save(testResult); + } + } + + public List<TestResult> findAllByTestId(String testId) { + return testResultRepository.findAllByTestId(testId); + } + + public double calculateMeanOfTestResults(List<TestResult> results) { + if (results.isEmpty()) { + return 0.0; + } + return results.stream() + .mapToInt(TestResult::getMarksAwarded) + .average() + .orElse(0.0); + } + + public double calculateMinOfTestResults(List<TestResult> results) { + if (results.isEmpty()) { + return 0.0; + } + return results + .stream() + .mapToDouble(TestResult::getMarksAwarded) + .min() + .orElse(0.0); + } + + public double calculateMaxOfTestResults(List<TestResult> results) { + if (results.isEmpty()) { + return 0.0; + } + return results + .stream() + .mapToDouble(TestResult::getMarksAwarded) + .max() + .orElse(0.0); + } + + public double calculateStandardDeviationOfTestResults(List<TestResult> results, double mean) { + if (results.isEmpty()) { + return 0.0; // or throw an exception if no results are found + } + + // Calculate the variance + double variance = results.stream() + .mapToDouble(result -> Math.pow(result.getMarksAwarded() - mean, 2)) + .average() + .orElse(0.0); + + // Return the standard deviation + return Math.sqrt(variance); + } + + public double calculatePercentile(List<Integer> sortedMarks, double percentile) { + if (sortedMarks.isEmpty()) { + return 0.0; + } + int index = (int) Math.floor(percentile / 100.0 * sortedMarks.size()) - 1; + return sortedMarks.get(Math.min(index, sortedMarks.size() - 1)); + } + + public List<Integer> getSortedMarks(List<TestResult> testResults) { + return testResults.stream() + .map(TestResult::getMarksAwarded) + .sorted() + .collect(Collectors.toList()); + } + + public double calculate25thPercentile(List<Integer> sortedMarks) { + return calculatePercentile(sortedMarks, 25.0); + } + + public double calculate50thPercentile(List<Integer> sortedMarks) { + return calculatePercentile(sortedMarks, 50.0); + } + + public double calculate75thPercentile(List<Integer> sortedMarks) { + return calculatePercentile(sortedMarks, 75.0); + } + + public AggregatedTestResultsDTO aggregateTestResults(String testId) { + List<TestResult> testResults = findAllByTestId(testId); + List<Integer> sortedMarks = getSortedMarks(testResults); + + AggregatedTestResultsDTO results = new AggregatedTestResultsDTO(); + + results.setMean(calculateMeanOfTestResults(testResults)); + + results.setStddev(calculateStandardDeviationOfTestResults(testResults, results.getMean())); + + results.setMin(calculateMinOfTestResults(testResults)); + + results.setMax(calculateMaxOfTestResults(testResults)); + + results.setP25(calculate25thPercentile(sortedMarks)); + + results.setP50(calculate50thPercentile(sortedMarks)); + + results.setP75(calculate75thPercentile(sortedMarks)); + + results.setCount(testResults.size()); + + return results; + } + +}
\ No newline at end of file |
