-
mamunozgil authoredc1884045
package de.hftstuttgart.dtabackend.utils;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.hftstuttgart.dtabackend.models.ExerciseCompetencyProfile;
import de.hftstuttgart.dtabackend.models.ICompetencyProfile;
import de.hftstuttgart.dtabackend.models.Result;
import de.hftstuttgart.dtabackend.models.ResultSummary;
import de.hftstuttgart.dtabackend.models.TestCompetencyProfile;
public class CompetencyAssessmentUtil {
private static final Logger LOG = LogManager.getLogger(CompetencyAssessmentUtil.class);
public static final String TEST_COMPETENCY_MANIFEST_FILE_NAME = "competency-tests.mft";
public static final String EXERCISE_COMPETENCY_MANIFEST_FILE_NAME = "exercise-tests.mft";
/**
* Retrieves the base directory where the test competency manifest is located
* by traversing upwards until it finds the file "exercise-tests.mft".
*
* @param startDir Starting directory path to begin the search
* @return Path of the base directory if found; otherwise, null
*/
public static Path getBaseDirectory(Path startDir) {
Path currentDir = startDir;
while (currentDir != null) {
Path manifestPath = currentDir.resolve(EXERCISE_COMPETENCY_MANIFEST_FILE_NAME);
if (Files.exists(manifestPath)) {
return currentDir;
}
currentDir = currentDir.getParent();
}
LOG.warn("Base directory with " + EXERCISE_COMPETENCY_MANIFEST_FILE_NAME + " not found starting from " + startDir);
return null;
}
/**
* Reads and loads test competency profiles from the base directory.
*
* @param exercisePath Path to the starting exercise directory
* @return List of TestCompetencyProfile instances loaded from the manifest
*/
public static List<TestCompetencyProfile> readTestCompetencyProfiles(Path exercisePath) {
Path baseDir = getBaseDirectory(exercisePath);
if (baseDir == null) {
LOG.error("Unable to locate the base directory for reading test competency profiles.");
return null;
}
return readTestCompetencyProfiles(baseDir, TEST_COMPETENCY_MANIFEST_FILE_NAME);
}
/**
* Reads and loads exercise competency profiles from the specified exercise directory.
*
* @param exercisePath Path to the exercise directory
* @return List of ExerciseCompetencyProfile instances loaded from the manifest
*/
public static List<ExerciseCompetencyProfile> readExerciseCompetencyProfiles(Path exercisePath) {
return readExerciseCompetencyProfiles(exercisePath, EXERCISE_COMPETENCY_MANIFEST_FILE_NAME);
}
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
private static List<TestCompetencyProfile> readTestCompetencyProfiles(Path baseDir, String fileName) {
List<TestCompetencyProfile> testCompetencyProfiles = new ArrayList<>();
Path manifestPath = baseDir.resolve(fileName);
try (BufferedReader testCompetencyManifest = new BufferedReader(new FileReader(manifestPath.toFile()))) {
String testEntry = testCompetencyManifest.readLine();
while (testEntry != null) {
String[] testEntryComponents = testEntry.split(ICompetencyProfile.COMPETENCY_SEPARATOR);
TestCompetencyProfile currentProfile = new TestCompetencyProfile();
currentProfile.testPackageName = testEntryComponents[0];
currentProfile.testClassName = testEntryComponents[1];
currentProfile.testName = testEntryComponents[2];
for (int competencyIndex = 0; competencyIndex < ICompetencyProfile.MAX_COMPETENCY_DIMENSIONS; competencyIndex++) {
currentProfile.competencyAssessments[competencyIndex] = Float.valueOf(testEntryComponents[competencyIndex + 3]);
}
testCompetencyProfiles.add(currentProfile);
testEntry = testCompetencyManifest.readLine();
}
LOG.info("Loaded " + testCompetencyProfiles.size() + " test competency profiles from " + manifestPath);
} catch (IOException e) {
LOG.error("Error reading test competency manifest file at " + manifestPath, e);
}
return testCompetencyProfiles;
}
private static List<ExerciseCompetencyProfile> readExerciseCompetencyProfiles(Path exercisePath, String fileName) {
List<ExerciseCompetencyProfile> exerciseCompetencyProfiles = new ArrayList<>();
Path manifestPath = exercisePath.resolve(fileName);
try (BufferedReader exerciseCompetencyManifest = new BufferedReader(new FileReader(manifestPath.toFile()))) {
String exerciseEntry = exerciseCompetencyManifest.readLine();
while (exerciseEntry != null) {
String[] exerciseEntryComponents = exerciseEntry.split(ExerciseCompetencyProfile.COMPETENCY_SEPARATOR);
ExerciseCompetencyProfile currentProfile = new ExerciseCompetencyProfile();
currentProfile.exerciseTopicName = exerciseEntryComponents[0];
currentProfile.exerciseName = exerciseEntryComponents[1];
currentProfile.exerciseURL = exerciseEntryComponents[2];
for (int competencyIndex = 0; competencyIndex < ExerciseCompetencyProfile.MAX_COMPETENCY_DIMENSIONS; competencyIndex++) {
currentProfile.competencyAssessments[competencyIndex] = Float.valueOf(exerciseEntryComponents[competencyIndex + 3]);
}
currentProfile.difficulty = Float.parseFloat(exerciseEntryComponents[19]);
exerciseCompetencyProfiles.add(currentProfile);
exerciseEntry = exerciseCompetencyManifest.readLine();
}
LOG.info("Loaded " + exerciseCompetencyProfiles.size() + " exercise competency profiles from " + manifestPath);
} catch (IOException e) {
LOG.error("Error reading exercise competency manifest file at " + manifestPath, e);
}
return exerciseCompetencyProfiles;
}
/**
* Converts an array of floats into a semicolon-separated string.
*
* @param array Array of float values to pack
* @return Semicolon-separated string of float values
*/
public static String packFloats(float[] array) {
return IntStream.range(0, array.length)
.mapToObj(i -> String.valueOf(array[i]))
.collect(Collectors.joining(";"));
}
/**
* Sums the competency profiles across all test competency profiles.
*
* @param testCompetencyProfiles List of test competency profiles
* @return An array representing the sum of competencies
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
*/
public static float[] sumTestCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles) {
float[] tcpTotalProfile = new float[ICompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
for (TestCompetencyProfile currentProfile : testCompetencyProfiles) {
tcpTotalProfile = ICompetencyProfile.competencySum(tcpTotalProfile, currentProfile.competencyAssessments);
}
return tcpTotalProfile;
}
/**
* Sums only the successful test competency profiles, based on the results summary.
*
* @param testCompetencyProfiles List of test competency profiles
* @param resultSummary The result summary containing test results
* @param success Indicates whether to sum successful (true) or unsuccessful (false) profiles
* @return An array representing the sum of competencies for successful or unsuccessful profiles
*/
public static float[] sumSuccessfulCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles, ResultSummary resultSummary, boolean success) {
float[] sumSuccessful = new float[ICompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
for (Result currentResult : resultSummary.results) {
boolean isSuccess = Integer.valueOf(currentResult.state).equals(Result.State.SUCCESS.ordinal());
if (isSuccess == success) {
TestCompetencyProfile currentProfile = new TestCompetencyProfile();
currentProfile.testPackageName = (currentResult.packageName != null) ? currentResult.packageName : "";
currentProfile.testClassName = (currentResult.className != null) ? currentResult.className : "";
currentProfile.testName = (currentResult.name != null) ? currentResult.name : "";
int testIndex = testCompetencyProfiles.indexOf(currentProfile);
if (testIndex != -1) {
sumSuccessful = ICompetencyProfile.competencySum(sumSuccessful, testCompetencyProfiles.get(testIndex).competencyAssessments);
}
}
}
return sumSuccessful;
}
/**
* Checks if all elements in the competency profile array are zero (indicating full success).
*
* @param competencyProfile Array of competency values
* @return True if all values are zero; false otherwise
*/
public static boolean isFullSuccess(float[] competencyProfile) {
for (float value : competencyProfile) {
if (value != 0.0f) {
return false;
}
}
return true;
}
}