File indexing completed on 2024-04-28 07:39:21

0001 /*
0002     SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "testentry.h"
0007 
0008 #include "prefs.h"
0009 
0010 TestEntry::TestEntry(KEduVocExpression *entry)
0011     : m_entry(entry)
0012     , m_languageFrom(998) // Bogus number to make sure that it's set correctly later
0013     , m_languageTo(999)
0014     , m_statisticCount(0)
0015     , m_statisticGoodCount(0)
0016     , m_statisticBadCount(0)
0017     , m_answeredCorrectInSequence(0)
0018     , m_correctAtFirstAttempt(false)
0019     , m_shouldChangeGrades(false)
0020     , m_isUnseenQuestion(false)
0021     , m_lastPercentage(0.0)
0022     , m_lastError()
0023 {
0024 }
0025 
0026 void TestEntry::setLanguageFrom(int from)
0027 {
0028     m_languageFrom = from;
0029 }
0030 
0031 void TestEntry::setLanguageTo(int to)
0032 {
0033     m_languageTo = to;
0034 }
0035 
0036 int TestEntry::answeredCorrectInSequence()
0037 {
0038     return m_answeredCorrectInSequence;
0039 }
0040 
0041 int TestEntry::statisticCount()
0042 {
0043     return m_statisticCount;
0044 }
0045 
0046 int TestEntry::statisticBadCount()
0047 {
0048     return m_statisticBadCount;
0049 }
0050 
0051 int TestEntry::statisticGoodCount()
0052 {
0053     return m_statisticGoodCount;
0054 }
0055 
0056 void TestEntry::updateStatisticsRightAnswer(grade_t currentPreGrade, grade_t currentGrade)
0057 {
0058     m_statisticCount++;
0059     m_statisticGoodCount++;
0060     m_answeredCorrectInSequence++;
0061     m_isUnseenQuestion = false;
0062 
0063     // Check if this is the first time the user is seeing this question (not practiced).
0064     if (currentPreGrade == KV_NORM_GRADE && currentGrade == KV_NORM_GRADE) {
0065         m_isUnseenQuestion = true;
0066     }
0067 
0068     m_shouldChangeGrades = true;
0069 
0070     // Make changes in statistics if answered correctly and not answered wrong in current test
0071     if (m_statisticBadCount == 0) {
0072         m_correctAtFirstAttempt = true;
0073     }
0074 }
0075 
0076 bool TestEntry::shouldChangeGrades()
0077 {
0078     return m_shouldChangeGrades;
0079 }
0080 
0081 void TestEntry::updateStatisticsWrongAnswer(grade_t currentPreGrade, grade_t currentGrade)
0082 {
0083     m_statisticCount++;
0084     m_statisticBadCount++;
0085     m_answeredCorrectInSequence = 0;
0086     m_shouldChangeGrades = true;
0087     m_isUnseenQuestion = false;
0088 
0089     if (currentPreGrade == KV_NORM_GRADE && currentGrade == KV_NORM_GRADE) {
0090         m_isUnseenQuestion = true;
0091     }
0092 }
0093 
0094 int TestEntry::languageFrom() const
0095 {
0096     return m_languageFrom;
0097 }
0098 
0099 int TestEntry::languageTo() const
0100 {
0101     return m_languageTo;
0102 }
0103 
0104 bool TestEntry::isUnseenQuestion() const
0105 {
0106     return m_isUnseenQuestion;
0107 }
0108 
0109 bool TestEntry::correctAtFirstAttempt()
0110 {
0111     return m_correctAtFirstAttempt;
0112 }
0113 
0114 void TestEntry::setLastErrors(TestEntry::ErrorTypes errorTypes)
0115 {
0116     m_lastError = errorTypes;
0117 }
0118 
0119 TestEntry::ErrorTypes TestEntry::lastErrors()
0120 {
0121     return m_lastError;
0122 }
0123 
0124 void TestEntry::setLastPercentage(double percent)
0125 {
0126     m_lastPercentage = percent;
0127 }
0128 
0129 double TestEntry::lastPercentage()
0130 {
0131     return m_lastPercentage;
0132 }
0133 
0134 KEduVocExpression *TestEntry::entry() const
0135 {
0136     return m_entry;
0137 }
0138 
0139 QString TestEntry::conjugationTense() const
0140 {
0141     return m_conjugationTense;
0142 }
0143 
0144 void TestEntry::setConjugationTense(const QString &tense)
0145 {
0146     m_conjugationTense = tense;
0147 }
0148 
0149 QList<KEduVocWordFlags> TestEntry::conjugationPronouns() const
0150 {
0151     return m_conjugationPronouns;
0152 }
0153 
0154 void TestEntry::setConjugationPronouns(const QList<KEduVocWordFlags> &flags)
0155 {
0156     m_conjugationPronouns = flags;
0157 }
0158 
0159 grade_t TestEntry::practiceModeDependentMinGrade() const
0160 {
0161     return practiceModeDependentGrade(&KEduVocTranslation::grade, qMin<grade_t>);
0162 }
0163 
0164 grade_t TestEntry::practiceModeDependentMinPreGrade() const
0165 {
0166     return practiceModeDependentGrade(&KEduVocText::preGrade, qMin<grade_t>);
0167 }
0168 
0169 grade_t TestEntry::practiceModeDependentMaxGrade() const
0170 {
0171     return practiceModeDependentGrade(&KEduVocText::grade, qMax<grade_t>);
0172 }
0173 
0174 grade_t TestEntry::practiceModeDependentMaxPreGrade() const
0175 {
0176     return practiceModeDependentGrade(&KEduVocText::preGrade, qMax<grade_t>);
0177 }
0178 
0179 grade_t TestEntry::practiceModeDependentGrade(std::function<grade_t(KEduVocText)> gradeFunc, std::function<grade_t(grade_t, grade_t)> minMaxFunc) const
0180 {
0181     grade_t result(0);
0182     const KEduVocTranslation *translation(entry()->translation(languageTo()));
0183     switch (Prefs::practiceMode()) {
0184     // For gender practice the article (pre-)grades are required.
0185     case Prefs::EnumPracticeMode::GenderPractice:
0186         result = gradeFunc(translation->article());
0187         break;
0188 
0189     // For conjugation practice the conjugation (pre-)grades are required.
0190     // For the specified tense the highest/lowest values of all specified gramatical persons
0191     // is evaluated.
0192     case Prefs::EnumPracticeMode::ConjugationPractice: {
0193         KEduVocConjugation conj(translation->getConjugation(conjugationTense()));
0194         // Depending on what minMaxFunc is used result needs an appropriate initialisation
0195         result = (minMaxFunc(0, 1) == 1) ? KV_MIN_GRADE : KV_MAX_GRADE;
0196         const QList<KEduVocWordFlags> conjugationPronouns = this->conjugationPronouns();
0197         for (KEduVocWordFlags pronoun : conjugationPronouns) {
0198             result = minMaxFunc(result, gradeFunc(conj.conjugation(pronoun)));
0199         }
0200     } break;
0201 
0202     // For comparison practice the (pre-)grades of the positive, comparative and superlative
0203     // are required. Then highest/lowest value is evaluated.
0204     case Prefs::EnumPracticeMode::ComparisonPractice: {
0205         result = gradeFunc(translation->comparativeForm());
0206         result = minMaxFunc(result, gradeFunc(translation->superlativeForm()));
0207     } break;
0208 
0209     // For all other practice forms the basic (pre-)grades are required.
0210     default:
0211         result = gradeFunc(*translation);
0212         break;
0213     }
0214     return result;
0215 }