/* * This file is part of ARSnova Backend. * Copyright (C) 2012-2017 The ARSnova Team * * ARSnova Backend is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ARSnova Backend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.thm.arsnova.domain; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.User; import de.thm.arsnova.entities.transport.LearningProgressValues; /** * Calculates learning progress based on overall correctness of an answer. A question is answered correctly if and * only if the maximum question value possible has been achieved. */ public class QuestionBasedLearningProgress extends VariantLearningProgress { public QuestionBasedLearningProgress(IDatabaseDao dao) { super(dao); } @Override protected LearningProgressValues createCourseProgress() { final int courseProgress = calculateCourseProgress(); final int numerator = courseScore.getQuestionCount() * courseProgress / 100; final int denominator = courseScore.getQuestionCount(); LearningProgressValues lpv = new LearningProgressValues(); lpv.setCourseProgress(courseProgress); lpv.setNumQuestions(courseScore.getQuestionCount()); lpv.setNumUsers(courseScore.getTotalUserCount()); lpv.setNumerator(numerator); lpv.setDenominator(denominator); return lpv; } private int calculateCourseProgress() { double ratio = 0; for (QuestionScore questionScore : courseScore) { if (!questionScore.hasScores()) { continue; } int numAnswers = questionScore.getUserCount(); if (numAnswers != 0) { ratio += (double) countCorrectAnswers(questionScore) / (numAnswers * courseScore.getQuestionCount()); } } return (int) Math.min(100, Math.round(ratio * 100)); } private int countCorrectAnswers(QuestionScore questionScore) { int requiredScore = questionScore.getMaximum(); int numAnswersCorrect = 0; for (UserScore userScore : questionScore) { if (userScore.hasScore(requiredScore)) { numAnswersCorrect++; } } return numAnswersCorrect; } @Override protected LearningProgressValues createMyProgress(User user) { final int numerator = numQuestionsCorrectForUser(user); final int denominator = courseScore.getQuestionCount(); LearningProgressValues lpv = new LearningProgressValues(); lpv.setCourseProgress(calculateCourseProgress()); lpv.setMyProgress(myPercentage(numerator, denominator)); lpv.setNumQuestions(courseScore.getQuestionCount()); lpv.setNumUsers(courseScore.getTotalUserCount()); lpv.setNumerator(numerator); lpv.setDenominator(denominator); return lpv; } private int numQuestionsCorrectForUser(User user) { int numQuestionsCorrect = 0; for (QuestionScore questionScore : courseScore) { numQuestionsCorrect += countCorrectAnswersForUser(user, questionScore); } return numQuestionsCorrect; } private int countCorrectAnswersForUser(User user, QuestionScore questionScore) { int numQuestionsCorrect = 0; int requiredScore = questionScore.getMaximum(); for (UserScore userScore : questionScore) { if (!userScore.isUser(user)) { continue; } if (userScore.hasScore(requiredScore)) { numQuestionsCorrect++; } } return numQuestionsCorrect; } private int myPercentage(int numQuestionsCorrect, int questionCount) { final double myLearningProgress = numQuestionsCorrect / (double) questionCount; return (int) Math.min(100, Math.round(myLearningProgress * 100)); } }