summaryrefslogtreecommitdiff
path: root/src/main/java/com/stileeducation/markr/service/TestResultsService.java
diff options
context:
space:
mode:
authorSzymon Szukalski <szymon@skas.io>2024-07-24 17:31:54 +1000
committerSzymon Szukalski <szymon@skas.io>2024-07-24 17:31:54 +1000
commitc459e7d5abd66d7bcf38e151aa2632fcb139f4f5 (patch)
tree2f19d20ed0cf9566eb4390f01ebf4d2be7fd6657 /src/main/java/com/stileeducation/markr/service/TestResultsService.java
parentf08b2fa7e6a977a18d6b9f14fb73c18ec73ec5df (diff)
Use Apache Commons Math for calculations and implement service tests
Implement TestResultService tests and supporting entity builders. Switch to Apache Commons Math library for descriptive statistics.
Diffstat (limited to 'src/main/java/com/stileeducation/markr/service/TestResultsService.java')
-rw-r--r--src/main/java/com/stileeducation/markr/service/TestResultsService.java82
1 files changed, 40 insertions, 42 deletions
diff --git a/src/main/java/com/stileeducation/markr/service/TestResultsService.java b/src/main/java/com/stileeducation/markr/service/TestResultsService.java
index 8d1b314..95b42f3 100644
--- a/src/main/java/com/stileeducation/markr/service/TestResultsService.java
+++ b/src/main/java/com/stileeducation/markr/service/TestResultsService.java
@@ -7,16 +7,18 @@ 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.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
+import org.apache.commons.math3.stat.descriptive.rank.Percentile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
-import java.util.stream.Collectors;
@Service
public class TestResultsService {
+ public static final boolean IS_BIAS_CORRECTED = false;
@Autowired
private TestResultRepository testResultRepository;
@@ -78,68 +80,64 @@ public class TestResultsService {
.orElse(0.0);
}
- public double calculateStandardDeviationOfTestResults(List<TestResult> results, double mean) {
+ public double calculateStandardDeviationOfTestResults(List<TestResult> results) {
if (results.isEmpty()) {
- return 0.0; // or throw an exception if no results are found
+ return 0.0;
}
+ double[] marks =
+ results.stream()
+ .mapToDouble(TestResult::getMarksAwarded)
+ .toArray();
- // 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);
+ StandardDeviation standardDeviation = new StandardDeviation(IS_BIAS_CORRECTED);
+ return standardDeviation.evaluate(marks);
}
- public double calculatePercentile(List<Integer> sortedMarks, double percentile) {
- if (sortedMarks.isEmpty()) {
+ public double calculate25thPercentile(List<TestResult> results) {
+ if (results.isEmpty()) {
return 0.0;
}
- int index = (int) Math.floor(percentile / 100.0 * sortedMarks.size()) - 1;
- return sortedMarks.get(Math.min(index, sortedMarks.size() - 1));
+ double[] marks =
+ results.stream()
+ .mapToDouble(TestResult::getMarksAwarded)
+ .toArray();
+ return new Percentile().evaluate(marks, 25.0);
}
- 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 calculate50thPercentile(List<TestResult> results) {
+ if (results.isEmpty()) {
+ return 0.0;
+ }
+ double[] marks =
+ results.stream()
+ .mapToDouble(TestResult::getMarksAwarded)
+ .toArray();
+ return new Percentile().evaluate(marks, 50.0);
}
- public double calculate75thPercentile(List<Integer> sortedMarks) {
- return calculatePercentile(sortedMarks, 75.0);
+ public double calculate75thPercentile(List<TestResult> results) {
+ if (results.isEmpty()) {
+ return 0.0;
+ }
+ double[] marks =
+ results.stream()
+ .mapToDouble(TestResult::getMarksAwarded)
+ .toArray();
+ return new Percentile().evaluate(marks, 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.setStddev(calculateStandardDeviationOfTestResults(testResults));
results.setMin(calculateMinOfTestResults(testResults));
-
results.setMax(calculateMaxOfTestResults(testResults));
-
- results.setP25(calculate25thPercentile(sortedMarks));
-
- results.setP50(calculate50thPercentile(sortedMarks));
-
- results.setP75(calculate75thPercentile(sortedMarks));
-
+ results.setP25(calculate25thPercentile(testResults));
+ results.setP50(calculate50thPercentile(testResults));
+ results.setP75(calculate75thPercentile(testResults));
results.setCount(testResults.size());
return results;