1 /*
2     SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #include "testentry.h"
7 
8 #include "prefs.h"
9 
TestEntry(KEduVocExpression * entry)10 TestEntry::TestEntry(KEduVocExpression *entry)
11     : m_entry(entry)
12     , m_languageFrom(998) // Bogus number to make sure that it's set correctly later
13     , m_languageTo(999)
14     , m_statisticCount(0)
15     , m_statisticGoodCount(0)
16     , m_statisticBadCount(0)
17     , m_answeredCorrectInSequence(0)
18     , m_correctAtFirstAttempt(false)
19     , m_shouldChangeGrades(false)
20     , m_isUnseenQuestion(false)
21     , m_lastPercentage(0.0)
22     , m_lastError()
23 {
24 }
25 
setLanguageFrom(int from)26 void TestEntry::setLanguageFrom(int from)
27 {
28     m_languageFrom = from;
29 }
30 
setLanguageTo(int to)31 void TestEntry::setLanguageTo(int to)
32 {
33     m_languageTo = to;
34 }
35 
answeredCorrectInSequence()36 int TestEntry::answeredCorrectInSequence()
37 {
38     return m_answeredCorrectInSequence;
39 }
40 
statisticCount()41 int TestEntry::statisticCount()
42 {
43     return m_statisticCount;
44 }
45 
statisticBadCount()46 int TestEntry::statisticBadCount()
47 {
48     return m_statisticBadCount;
49 }
50 
statisticGoodCount()51 int TestEntry::statisticGoodCount()
52 {
53     return m_statisticGoodCount;
54 }
55 
updateStatisticsRightAnswer(grade_t currentPreGrade,grade_t currentGrade)56 void TestEntry::updateStatisticsRightAnswer(grade_t currentPreGrade, grade_t currentGrade)
57 {
58     m_statisticCount++;
59     m_statisticGoodCount++;
60     m_answeredCorrectInSequence++;
61     m_isUnseenQuestion = false;
62 
63     // Check if this is the first time the user is seeing this question (not practiced).
64     if (currentPreGrade == KV_NORM_GRADE && currentGrade == KV_NORM_GRADE) {
65         m_isUnseenQuestion = true;
66     }
67 
68     m_shouldChangeGrades = true;
69 
70     // Make changes in statistics if answered correctly and not answered wrong in current test
71     if (m_statisticBadCount == 0) {
72         m_correctAtFirstAttempt = true;
73     }
74 }
75 
shouldChangeGrades()76 bool TestEntry::shouldChangeGrades()
77 {
78     return m_shouldChangeGrades;
79 }
80 
updateStatisticsWrongAnswer(grade_t currentPreGrade,grade_t currentGrade)81 void TestEntry::updateStatisticsWrongAnswer(grade_t currentPreGrade, grade_t currentGrade)
82 {
83     m_statisticCount++;
84     m_statisticBadCount++;
85     m_answeredCorrectInSequence = 0;
86     m_shouldChangeGrades = true;
87     m_isUnseenQuestion = false;
88 
89     if (currentPreGrade == KV_NORM_GRADE && currentGrade == KV_NORM_GRADE) {
90         m_isUnseenQuestion = true;
91     }
92 }
93 
languageFrom() const94 int TestEntry::languageFrom() const
95 {
96     return m_languageFrom;
97 }
98 
languageTo() const99 int TestEntry::languageTo() const
100 {
101     return m_languageTo;
102 }
103 
isUnseenQuestion() const104 bool TestEntry::isUnseenQuestion() const
105 {
106     return m_isUnseenQuestion;
107 }
108 
correctAtFirstAttempt()109 bool TestEntry::correctAtFirstAttempt()
110 {
111     return m_correctAtFirstAttempt;
112 }
113 
setLastErrors(TestEntry::ErrorTypes errorTypes)114 void TestEntry::setLastErrors(TestEntry::ErrorTypes errorTypes)
115 {
116     m_lastError = errorTypes;
117 }
118 
lastErrors()119 TestEntry::ErrorTypes TestEntry::lastErrors()
120 {
121     return m_lastError;
122 }
123 
setLastPercentage(double percent)124 void TestEntry::setLastPercentage(double percent)
125 {
126     m_lastPercentage = percent;
127 }
128 
lastPercentage()129 double TestEntry::lastPercentage()
130 {
131     return m_lastPercentage;
132 }
133 
entry() const134 KEduVocExpression *TestEntry::entry() const
135 {
136     return m_entry;
137 }
138 
conjugationTense() const139 QString TestEntry::conjugationTense() const
140 {
141     return m_conjugationTense;
142 }
143 
setConjugationTense(const QString & tense)144 void TestEntry::setConjugationTense(const QString &tense)
145 {
146     m_conjugationTense = tense;
147 }
148 
conjugationPronouns() const149 QList<KEduVocWordFlags> TestEntry::conjugationPronouns() const
150 {
151     return m_conjugationPronouns;
152 }
153 
setConjugationPronouns(const QList<KEduVocWordFlags> & flags)154 void TestEntry::setConjugationPronouns(const QList<KEduVocWordFlags> &flags)
155 {
156     m_conjugationPronouns = flags;
157 }
158 
practiceModeDependentMinGrade() const159 grade_t TestEntry::practiceModeDependentMinGrade() const
160 {
161     return practiceModeDependentGrade(&KEduVocTranslation::grade, qMin<grade_t>);
162 }
163 
practiceModeDependentMinPreGrade() const164 grade_t TestEntry::practiceModeDependentMinPreGrade() const
165 {
166     return practiceModeDependentGrade(&KEduVocText::preGrade, qMin<grade_t>);
167 }
168 
practiceModeDependentMaxGrade() const169 grade_t TestEntry::practiceModeDependentMaxGrade() const
170 {
171     return practiceModeDependentGrade(&KEduVocText::grade, qMax<grade_t>);
172 }
173 
practiceModeDependentMaxPreGrade() const174 grade_t TestEntry::practiceModeDependentMaxPreGrade() const
175 {
176     return practiceModeDependentGrade(&KEduVocText::preGrade, qMax<grade_t>);
177 }
178 
practiceModeDependentGrade(std::function<grade_t (KEduVocText)> gradeFunc,std::function<grade_t (grade_t,grade_t)> minMaxFunc) const179 grade_t TestEntry::practiceModeDependentGrade(std::function<grade_t(KEduVocText)> gradeFunc, std::function<grade_t(grade_t, grade_t)> minMaxFunc) const
180 {
181     grade_t result(0);
182     const KEduVocTranslation *translation(entry()->translation(languageTo()));
183     switch (Prefs::practiceMode()) {
184     // For gender practice the article (pre-)grades are required.
185     case Prefs::EnumPracticeMode::GenderPractice:
186         result = gradeFunc(translation->article());
187         break;
188 
189     // For conjugation practice the conjugation (pre-)grades are required.
190     // For the specified tense the highest/lowest values of all specified gramatical persons
191     // is evaluated.
192     case Prefs::EnumPracticeMode::ConjugationPractice: {
193         KEduVocConjugation conj(translation->getConjugation(conjugationTense()));
194         // Depending on what minMaxFunc is used result needs an appropriate initialisation
195         result = (minMaxFunc(0, 1) == 1) ? KV_MIN_GRADE : KV_MAX_GRADE;
196         const QList<KEduVocWordFlags> conjugationPronouns = this->conjugationPronouns();
197         for (KEduVocWordFlags pronoun : conjugationPronouns) {
198             result = minMaxFunc(result, gradeFunc(conj.conjugation(pronoun)));
199         }
200     } break;
201 
202     // For comparison practice the (pre-)grades of the positive, comparative and superlative
203     // are required. Then highest/lowest value is evaluated.
204     case Prefs::EnumPracticeMode::ComparisonPractice: {
205         result = gradeFunc(translation->comparativeForm());
206         result = minMaxFunc(result, gradeFunc(translation->superlativeForm()));
207     } break;
208 
209     // For all other practice forms the basic (pre-)grades are required.
210     default:
211         result = gradeFunc(*translation);
212         break;
213     }
214     return result;
215 }
216