use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class LearningGoalService method findLastResultOfExerciseInListOfParticipations.
/**
* Finds the latest result for a given exercise in a list of relevant participations
* @param exercise exercise to find the result for
* @param participationsList participations with submissions and results that should be checked
* @return optional containing the last result or else an empty optional
*/
private Optional<Result> findLastResultOfExerciseInListOfParticipations(Exercise exercise, List<StudentParticipation> participationsList) {
// find the relevant participation
StudentParticipation relevantParticipation = exercise.findRelevantParticipation(participationsList);
if (relevantParticipation == null) {
return Optional.empty();
}
relevantParticipation.setSubmissions(relevantParticipation.getSubmissions().stream().filter(submission -> {
boolean hasFittingResult = false;
for (Result result : submission.getResults()) {
if (result.getScore() != null && result.getCompletionDate() != null) {
hasFittingResult = true;
break;
}
}
return hasFittingResult;
}).collect(Collectors.toSet()));
// find the latest submission of the relevant participation
Optional<Submission> latestSubmissionOptional = relevantParticipation.findLatestSubmission();
if (latestSubmissionOptional.isEmpty()) {
return Optional.empty();
}
Submission latestSubmission = latestSubmissionOptional.get();
latestSubmission.setResults(latestSubmission.getResults().stream().filter(result -> result.getScore() != null && result.getCompletionDate() != null).collect(Collectors.toList()));
// find the latest result of the latest submission
Result latestResult = latestSubmission.getLatestResult();
return latestResult == null ? Optional.empty() : Optional.of(latestResult);
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class AssessmentDashboardService method generateStatisticsForExercisesForAssessmentDashboard.
/**
* Prepares the exercises for the assessment dashboard by setting the tutor participations and statistics
* This is very slow as each iteration takes about 2.5 s
* @param exercises exercises to be prepared for the assessment dashboard
* @param tutorParticipations participations of the tutors
* @param examMode flag should be set for exam dashboard
*/
public void generateStatisticsForExercisesForAssessmentDashboard(Set<Exercise> exercises, List<TutorParticipation> tutorParticipations, boolean examMode) {
log.debug("generateStatisticsForExercisesForAssessmentDashboard invoked");
// start measures performance of each individual query, start2 measures performance of one loop iteration
long start = System.nanoTime();
long start2 = System.nanoTime();
long startComplete = System.nanoTime();
Set<Exercise> programmingExerciseIds = exercises.stream().filter(exercise -> exercise instanceof ProgrammingExercise).collect(Collectors.toSet());
Set<Exercise> nonProgrammingExerciseIds = exercises.stream().filter(exercise -> !(exercise instanceof ProgrammingExercise)).collect(Collectors.toSet());
complaintService.calculateNrOfOpenComplaints(exercises, examMode);
log.debug("Finished >> complaintService.calculateNrOfOpenComplaints all << in {}", TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
calculateNumberOfSubmissions(programmingExerciseIds, nonProgrammingExerciseIds, examMode);
log.debug("Finished >> assessmentDashboardService.calculateNumberOfSubmissions all << in {}", TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
// parts of this loop can possibly still be extracted
for (Exercise exercise : exercises) {
DueDateStat totalNumberOfAssessments;
if (exercise instanceof ProgrammingExercise) {
totalNumberOfAssessments = new DueDateStat(programmingExerciseRepository.countAssessmentsByExerciseIdSubmitted(exercise.getId(), examMode), 0L);
log.debug("Finished >> programmingExerciseRepository.countAssessmentsByExerciseIdSubmitted << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
} else {
totalNumberOfAssessments = resultRepository.countNumberOfFinishedAssessmentsForExercise(exercise.getId(), examMode);
log.debug("Finished >> resultRepository.countNumberOfFinishedAssessmentsForExercise << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
}
start = System.nanoTime();
final DueDateStat[] numberOfAssessmentsOfCorrectionRounds;
if (examMode) {
// set number of corrections specific to each correction round
int numberOfCorrectionRounds = exercise.getExerciseGroup().getExam().getNumberOfCorrectionRoundsInExam();
numberOfAssessmentsOfCorrectionRounds = resultRepository.countNumberOfFinishedAssessmentsForExamExerciseForCorrectionRounds(exercise, numberOfCorrectionRounds);
log.debug("Finished >> resultRepository.countNumberOfFinishedAssessmentsForExamExerciseForCorrectionRounds << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
} else {
// no examMode here, so correction rounds defaults to 1 and is the same as totalNumberOfAssessments
numberOfAssessmentsOfCorrectionRounds = new DueDateStat[] { totalNumberOfAssessments };
}
exercise.setNumberOfAssessmentsOfCorrectionRounds(numberOfAssessmentsOfCorrectionRounds);
exercise.setTotalNumberOfAssessments(numberOfAssessmentsOfCorrectionRounds[0]);
start = System.nanoTime();
Set<ExampleSubmission> exampleSubmissions = exampleSubmissionRepository.findAllWithResultByExerciseId(exercise.getId());
log.debug("Finished >> exampleSubmissionRepository.findAllWithResultByExerciseId << call for course {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
// Do not provide example submissions without any assessment
exampleSubmissions.removeIf(exampleSubmission -> exampleSubmission.getSubmission() == null || exampleSubmission.getSubmission().getLatestResult() == null);
exercise.setExampleSubmissions(exampleSubmissions);
TutorParticipation tutorParticipation = tutorParticipations.stream().filter(participation -> participation.getAssessedExercise().getId().equals(exercise.getId())).findFirst().orElseGet(() -> {
TutorParticipation emptyTutorParticipation = new TutorParticipation();
emptyTutorParticipation.setStatus(TutorParticipationStatus.NOT_PARTICIPATED);
return emptyTutorParticipation;
});
exercise.setTutorParticipations(Collections.singleton(tutorParticipation));
var exerciseRating = ratingService.averageRatingByExerciseId(exercise.getId());
exercise.setAverageRating(exerciseRating.averageRating());
exercise.setNumberOfRatings(exerciseRating.numberOfRatings());
log.debug("Finished >> assessmentDashboardLoopIteration << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start2));
}
log.debug("Finished >> generateStatisticsForExercisesForAssessmentDashboard << call in {}", TimeLogUtil.formatDurationFrom(startComplete));
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class ModelingSubmissionService method save.
/**
* Saves the given submission and the corresponding model and creates the result if necessary. This method used for creating and updating modeling submissions.
*
* @param modelingSubmission the submission that should be saved
* @param modelingExercise the exercise the submission belongs to
* @param username the name of the corresponding user
* @return the saved modelingSubmission entity
*/
public ModelingSubmission save(ModelingSubmission modelingSubmission, ModelingExercise modelingExercise, String username) {
Optional<StudentParticipation> optionalParticipation = participationService.findOneByExerciseAndStudentLoginWithEagerSubmissionsAnyState(modelingExercise, username);
if (optionalParticipation.isEmpty()) {
throw new EntityNotFoundException("No participation found for " + username + " in exercise with id " + modelingExercise.getId());
}
StudentParticipation participation = optionalParticipation.get();
final Optional<ZonedDateTime> dueDate = exerciseDateService.getDueDate(participation);
if (dueDate.isPresent() && exerciseDateService.isAfterDueDate(participation) && participation.getInitializationDate().isBefore(dueDate.get())) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
// remove result from submission (in the unlikely case it is passed here), so that students cannot inject a result
modelingSubmission.setResults(new ArrayList<>());
// NOTE: from now on we always set submitted to true to prevent problems here! Except for late submissions of course exercises to prevent issues in auto-save
if (modelingExercise.isExamExercise() || exerciseDateService.isBeforeDueDate(participation)) {
modelingSubmission.setSubmitted(true);
}
modelingSubmission.setSubmissionDate(ZonedDateTime.now());
modelingSubmission.setType(SubmissionType.MANUAL);
modelingSubmission.setParticipation(participation);
modelingSubmission = modelingSubmissionRepository.save(modelingSubmission);
// versioning of submission
try {
if (modelingExercise.isTeamMode()) {
submissionVersionService.saveVersionForTeam(modelingSubmission, username);
} else if (modelingExercise.isExamExercise()) {
submissionVersionService.saveVersionForIndividual(modelingSubmission, username);
}
} catch (Exception ex) {
log.error("Modeling submission version could not be saved", ex);
}
participation.addSubmission(modelingSubmission);
participation.setInitializationState(InitializationState.FINISHED);
StudentParticipation savedParticipation = studentParticipationRepository.save(participation);
if (modelingSubmission.getId() == null) {
Optional<Submission> optionalSubmission = savedParticipation.findLatestSubmission();
if (optionalSubmission.isPresent()) {
modelingSubmission = (ModelingSubmission) optionalSubmission.get();
}
}
log.debug("return model: {}", modelingSubmission.getModel());
return modelingSubmission;
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class ExampleSubmissionService method importStudentSubmissionAsExampleSubmission.
/**
* Creates new example submission by copying the student submission with its assessments
* calls copySubmission of required service depending on type of exercise
*
* @param submissionId The original student submission id to be copied
* @param exercise The exercise to which the example submission belongs
* @return the exampleSubmission entity
*/
public ExampleSubmission importStudentSubmissionAsExampleSubmission(Long submissionId, Exercise exercise) {
ExampleSubmission newExampleSubmission = new ExampleSubmission();
newExampleSubmission.setExercise(exercise);
if (exercise instanceof ModelingExercise) {
ModelingSubmission modelingSubmission = (ModelingSubmission) submissionRepository.findOneWithEagerResultAndFeedback(submissionId);
checkGivenExerciseIdSameForSubmissionParticipation(exercise.getId(), modelingSubmission.getParticipation().getExercise().getId());
// example submission does not need participation
modelingSubmission.setParticipation(null);
newExampleSubmission.setSubmission(modelingExerciseImportService.copySubmission(modelingSubmission, new HashMap<>()));
}
if (exercise instanceof TextExercise) {
TextSubmission textSubmission = textSubmissionRepository.findByIdWithEagerResultsAndFeedbackAndTextBlocksElseThrow(submissionId);
checkGivenExerciseIdSameForSubmissionParticipation(exercise.getId(), textSubmission.getParticipation().getExercise().getId());
// example submission does not need participation
textSubmission.setParticipation(null);
newExampleSubmission.setSubmission(textExerciseImportService.copySubmission(textSubmission));
}
return exampleSubmissionRepository.save(newExampleSubmission);
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class TextAssessmentQueueService method calculateSmallerClusterPercentageBatch.
/**
* Calculates the Percentages of Smaller Clusters for a list of textSubmissions
* All TextSubmissions must have the same exercise
* @param textSubmissionList for which the smaller clusters should be calculated
* @throws IllegalArgumentException if not all TextSubmissions are from the same exercise
* @return return a map where the textBlock is the key and smaller cluster percentage is the value
* If a textBlock has no cluster or is already assessable, it isn't in the map
*/
public Map<TextBlock, Double> calculateSmallerClusterPercentageBatch(List<TextSubmission> textSubmissionList) {
Map<TextBlock, Double> result = new HashMap<>();
if (textSubmissionList.isEmpty()) {
return result;
}
Participation participation = textSubmissionList.get(0).getParticipation();
TextExercise currentExercise = (TextExercise) participation.getExercise();
List<TextCluster> clusters = textClusterRepository.findAllByExercise(currentExercise);
if (textSubmissionList.stream().map(submission -> submission.getParticipation().getExercise()).anyMatch(elem -> elem != currentExercise)) {
throw new IllegalArgumentException("All TextSubmissions have to be from the same Exercise");
}
textSubmissionList.forEach(textSubmission -> {
textSubmission.getBlocks().forEach(textBlock -> {
if (textBlock.getCluster() == null) {
return;
}
OptionalInt optionalLargestClusterSize = clusters.stream().mapToInt(TextCluster::openTextBlockCount).max();
// if cluster is empty
if (optionalLargestClusterSize.isEmpty()) {
result.put(textBlock, 0.0);
return;
}
// if cluster is the largest set to smaller percentage to 1
if (optionalLargestClusterSize.getAsInt() == textBlock.getCluster().openTextBlockCount()) {
result.put(textBlock, 1.0);
return;
}
int smallerClusterCount = clusters.stream().mapToInt(TextCluster::openTextBlockCount).reduce(0, (sum, elem) -> {
if (elem < textBlock.getCluster().openTextBlockCount()) {
return sum + 1;
}
return sum;
});
result.put(textBlock, (double) smallerClusterCount / clusters.size());
});
});
return result;
}
Aggregations