use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class FileUploadSubmissionService method lockAndGetFileUploadSubmissionWithoutResult.
/**
* Get a file upload submission of the given exercise that still needs to be assessed and lock the submission to prevent other tutors from receiving and assessing it.
*
* @param fileUploadExercise the exercise the submission should belong to
* @param correctionRound - the correction round we want our submission to have results for
* @param ignoreTestRunParticipations flag to determine if test runs should be removed. This should be set to true for exam exercises
* @return a locked file upload submission that needs an assessment
*/
public FileUploadSubmission lockAndGetFileUploadSubmissionWithoutResult(FileUploadExercise fileUploadExercise, boolean ignoreTestRunParticipations, int correctionRound) {
FileUploadSubmission fileUploadSubmission = getRandomFileUploadSubmissionEligibleForNewAssessment(fileUploadExercise, ignoreTestRunParticipations, correctionRound).orElseThrow(() -> new EntityNotFoundException("File upload submission for exercise " + fileUploadExercise.getId() + " could not be found"));
lockSubmission(fileUploadSubmission, correctionRound);
return fileUploadSubmission;
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class GradingScaleService method saveGradingScale.
/**
* Saves a grading scale to the database if it is valid
* - grading scale can't have both course and exam set
* - other checks performed in {@link GradingScaleService#checkGradeStepValidity(Set)}
*
* @param gradingScale the grading scale to be saved
* @return the saved grading scale
*/
public GradingScale saveGradingScale(GradingScale gradingScale) {
if (gradingScale.getCourse() != null && gradingScale.getExam() != null) {
throw new BadRequestAlertException("Grading scales can't belong both to a course and an exam", "gradingScale", "gradingScaleBelongsToCourseAndExam");
}
Set<GradeStep> gradeSteps = gradingScale.getGradeSteps();
checkGradeStepValidity(gradeSteps);
for (GradeStep gradeStep : gradeSteps) {
gradeStep.setGradingScale(gradingScale);
}
gradingScale.setGradeSteps(gradeSteps);
return gradingScaleRepository.save(gradingScale);
}
use of de.tum.in.www1.artemis.domain.exam.Exam 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.exam.Exam in project ArTEMiS by ls1intum.
the class ModelingSubmissionService method findRandomSubmissionWithoutExistingAssessment.
/**
* retrieves a modeling submission without assessment for the specified correction round and potentially locks the submission
*
* In case Compass is supported (and activated), this method also assigns a result with feedback suggestions to the submission
*
* @param lockSubmission whether the submission should be locked
* @param correctionRound the correction round (0 = first correction, 1 = second correction
* @param modelingExercise the modeling exercise for which a
* @param isExamMode whether the exercise belongs to an exam
* @return a random modeling submission (potentially based on compass)
*/
public ModelingSubmission findRandomSubmissionWithoutExistingAssessment(boolean lockSubmission, int correctionRound, ModelingExercise modelingExercise, boolean isExamMode) {
var submissionWithoutResult = super.getRandomSubmissionEligibleForNewAssessment(modelingExercise, isExamMode, correctionRound).orElseThrow(() -> new EntityNotFoundException("Modeling submission for exercise " + modelingExercise.getId() + " could not be found"));
ModelingSubmission modelingSubmission = (ModelingSubmission) submissionWithoutResult;
if (lockSubmission) {
if (compassService.isSupported(modelingExercise) && correctionRound == 0L) {
modelingSubmission = assignResultWithFeedbackSuggestionsToSubmission(modelingSubmission, modelingExercise);
setNumberOfAffectedSubmissionsPerElement(modelingSubmission);
}
lockSubmission(modelingSubmission, correctionRound);
}
return modelingSubmission;
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class AbstractSubmissionResource method getAllSubmissions.
/**
* Get all the submissions for an exercise. It is possible to filter, to receive only the ones that have already been submitted, or only the ones assessed by the tutor who is
* doing the call. In case of exam exercise, it filters out all test run submissions.
*
* @param exerciseId the id of the exercise
* @param submittedOnly if only submitted submissions should be returned
* @param assessedByTutor if the submission was assessed by calling tutor
* @return the ResponseEntity with status 200 (OK) and the list of submissions in body
*/
protected ResponseEntity<List<Submission>> getAllSubmissions(Long exerciseId, boolean submittedOnly, boolean assessedByTutor, int correctionRound) {
User user = userRepository.getUserWithGroupsAndAuthorities();
Exercise exercise = exerciseRepository.findByIdElseThrow(exerciseId);
if (assessedByTutor) {
authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.TEACHING_ASSISTANT, exercise, user);
} else {
authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.INSTRUCTOR, exercise, user);
}
final boolean examMode = exercise.isExamExercise();
List<Submission> submissions;
if (assessedByTutor) {
submissions = submissionService.getAllSubmissionsAssessedByTutorForCorrectionRoundAndExercise(exerciseId, user, examMode, correctionRound);
} else {
submissions = submissionService.getAllSubmissionsForExercise(exerciseId, submittedOnly, examMode);
}
// tutors should not see information about the student of a submission
if (!authCheckService.isAtLeastInstructorForExercise(exercise, user)) {
submissions.forEach(submission -> submissionService.hideDetails(submission, user));
}
// remove unnecessary data from the REST response
submissions.forEach(submission -> {
if (submission.getParticipation() != null && submission.getParticipation().getExercise() != null) {
submission.getParticipation().setExercise(null);
}
});
return ResponseEntity.ok().body(submissions);
}
Aggregations