diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/api/managers/StatisticsManager.java b/src/main/java/uk/ac/cam/cl/dtg/segue/api/managers/StatisticsManager.java index 0ddb43f92a..b241aa0564 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/api/managers/StatisticsManager.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/api/managers/StatisticsManager.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.ac.cam.cl.dtg.isaac.api.managers.GameManager; +import uk.ac.cam.cl.dtg.isaac.api.managers.UserAttemptManager; import uk.ac.cam.cl.dtg.isaac.api.services.ContentSummarizerService; import uk.ac.cam.cl.dtg.isaac.dos.AudienceContext; import uk.ac.cam.cl.dtg.isaac.dos.Difficulty; @@ -196,8 +197,8 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us Map> questionsCorrectByStageAndDifficultyStats = Maps.newHashMap(); Map questionAttemptsByTypeStats = Maps.newHashMap(); Map questionsCorrectByTypeStats = Maps.newHashMap(); - List incompleteQuestionPages = Lists.newArrayList(); - Queue mostRecentlyAttemptedQuestionPages = new CircularFifoQueue<>(PROGRESS_MAX_RECENT_QUESTIONS); + List incompleteQuestionPages = Lists.newArrayList(); + Queue mostRecentlyAttemptedQuestionsQueue = new CircularFifoQueue<>(PROGRESS_MAX_RECENT_QUESTIONS); LocalDate now = LocalDate.now(); LocalDate endOfAugustThisYear = LocalDate.of(now.getYear(), Month.AUGUST, 31); @@ -218,14 +219,17 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us } IsaacQuestionPageDTO questionPageDTO = (IsaacQuestionPageDTO) contentDTO; - mostRecentlyAttemptedQuestionPages.add(questionPageDTO); // Assumes questionAttemptsByUser is sorted! attemptedQuestions++; boolean questionIsCorrect = true; // Are all Parts of the Question correct? LocalDate mostRecentCorrectQuestionPart = null; LocalDate mostRecentAttemptAtQuestion = null; + int questionPartsCorrect = 0; + int questionPartsIncorrect = 0; + int questionPartsTotal = 0; // Loop through each Part of the Question: for (QuestionDTO questionPart : GameManager.getAllMarkableQuestionPartsDFSOrder(questionPageDTO)) { + questionPartsTotal++; boolean questionPartIsCorrect = false; // Is this Part of the Question correct? // Has the user attempted this part of the question at all? if (question.getValue().containsKey(questionPart.getId())) { @@ -251,6 +255,7 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us questionPartIsCorrect = true; break; // early so that later attempts are ignored } + } // Type Stats - Count the attempt at the Question Part: @@ -278,6 +283,10 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us } else { questionsCorrectByTypeStats.put(questionPartType, 1); } + + questionPartsCorrect++; + } else { + questionPartsIncorrect++; } } @@ -285,6 +294,11 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us questionIsCorrect = questionIsCorrect && questionPartIsCorrect; } + // Convert QuestionPageDTO to ContentSummaryDTO and calculate completion state + ContentSummaryDTO contentSummaryDTO = contentSummarizerService.extractContentSummary(questionPageDTO); + contentSummaryDTO.setState(UserAttemptManager.getCompletionState(questionPartsTotal, questionPartsCorrect, questionPartsIncorrect)); + mostRecentlyAttemptedQuestionsQueue.add(contentSummaryDTO); + // Tag Stats - Loop through the Question's tags: for (String tag : questionPageDTO.getTags()) { // Count the attempt at the Question: @@ -355,21 +369,17 @@ public Map getUserQuestionInformation(final RegisteredUserDTO us correctQuestionsThisAcademicYear++; } } else { - incompleteQuestionPages.add(questionPageDTO); + incompleteQuestionPages.add(contentSummaryDTO); } } // Collate all the information into the JSON response as a Map: Map questionInfo = Maps.newHashMap(); - - // Create the recent and unanswered question lists: - List mostRecentlyAttemptedQuestionsList = mostRecentlyAttemptedQuestionPages - .stream().map(contentSummarizerService::extractContentSummary).collect(Collectors.toList()); + List mostRecentlyAttemptedQuestionsList = new ArrayList<>(mostRecentlyAttemptedQuestionsQueue); Collections.reverse(mostRecentlyAttemptedQuestionsList); // We want most-recent first order and streams cannot reverse. List questionsNotCompleteList = incompleteQuestionPages.stream() - .sorted(Comparator.comparing(SeguePageDTO::getDeprecated, Comparator.nullsFirst(Comparator.naturalOrder()))) - .limit(PROGRESS_MAX_RECENT_QUESTIONS) - .map(contentSummarizerService::extractContentSummary).collect(Collectors.toList()); + .sorted(Comparator.comparing(ContentSummaryDTO::getDeprecated, Comparator.nullsFirst(Comparator.naturalOrder()))) + .limit(PROGRESS_MAX_RECENT_QUESTIONS).collect(Collectors.toList()); questionInfo.put("totalQuestionsAttempted", attemptedQuestions); questionInfo.put("totalQuestionsCorrect", correctQuestions);