• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

parley

  • sources
  • kde-4.12
  • kdeedu
  • parley
  • src
  • practice
testentrymanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
3  (C) 2005-2007 Peter Hedlund <peter.hedlund@kdemail.net>
4  (C) 2007-2009 Frederik Gladhorn <gladhorn@kde.org>
5  ***************************************************************************/
6 
7 /***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "testentrymanager.h"
17 
18 #include "entryfilter.h"
19 
20 #include <prefs.h>
21 #include <klocale.h>
22 #include <kconfig.h>
23 
24 #include <keduvoclesson.h>
25 #include <keduvocexpression.h>
26 #include <keduvocdocument.h>
27 
28 #include <KDebug>
29 #include <KMessageBox>
30 #include <QDateTime>
31 
32 using namespace Practice;
33 
34 TestEntryManager::TestEntryManager(QWidget* parent)
35  :m_parent(parent)
36  ,m_fromTranslation(0)
37  ,m_toTranslation(1)
38  ,m_currentEntry(-1)
39  ,m_totalTime(0)
40  ,m_randomSequence(QDateTime::currentDateTime().toTime_t())
41 {
42 }
43 
44 TestEntryManager::~TestEntryManager()
45 {
46 
47  qDeleteAll(m_allTestEntries);
48 }
49 
50 void TestEntryManager::setDocument(KEduVocDocument* doc)
51 {
52  qDeleteAll(m_allTestEntries);
53  m_allTestEntries.clear();
54  m_notAskedTestEntries.clear();
55  m_currentEntries.clear();
56 
57  m_doc = doc;
58 
59  // don't crash when trying to start practicing a document containing only one language
60  if (m_doc->identifierCount() < 2) {
61  KMessageBox::error(0, i18n("The vocabulary collection contains fewer than two languages.", i18n("Could not start practice")));
62  return;
63  }
64  if (Prefs::questionLanguage() >= m_doc->identifierCount() || Prefs::solutionLanguage() >= m_doc->identifierCount()) {
65  kDebug() << "Invalid language selection" << m_fromTranslation << " to " << m_toTranslation;
66  Prefs::setQuestionLanguage(0);
67  Prefs::setSolutionLanguage(1);
68  }
69 
70  setLanguages(Prefs::questionLanguage(), Prefs::solutionLanguage());
71  kDebug() << "Test from: " << m_doc->identifier(m_fromTranslation).name()
72  << " to: " << m_doc->identifier(m_toTranslation).name();
73 
74  filterTestEntries();
75  kDebug() << "Found " << m_allTestEntries.count() << " entries after filtering.";
76 
77  m_notAskedTestEntries = m_allTestEntries;
78 
79  for ( int i = 0; i < qMin(m_notAskedTestEntries.count(), Prefs::testNumberOfEntries() ); i++ ) {
80  m_currentEntries.append( m_notAskedTestEntries.takeAt(0) );
81  }
82 }
83 
84 void TestEntryManager::setLanguages(int from, int to)
85 {
86  m_fromTranslation = from;
87  m_toTranslation = to;
88  TestEntry::setGradeFrom(m_fromTranslation);
89  TestEntry::setGradeTo(m_toTranslation);
90 }
91 
92 void TestEntryManager::filterTestEntries()
93 {
94  EntryFilter filter(m_parent, m_doc);
95  m_allTestEntries = filter.entries();
96 }
97 
98 void TestEntryManager::removeCurrentEntryFromPractice()
99 {
100  if (m_currentEntry >= 0) {
101  m_currentEntries.takeAt(m_currentEntry);
102  }
103 }
104 
105 void TestEntryManager::printStatistics()
106 {
107  kDebug() << "Test statistics: ";
108  foreach ( TestEntry* entry, m_allTestEntries ) {
109  kDebug()
110  << " asked: " << entry->statisticCount()
111  << " +" << entry->statisticGoodCount() << " -" << entry->statisticBadCount()
112  << "Entry: " << entry->entry()->translation(0)->text();
113  }
114 }
115 
116 int TestEntryManager::totalTime()
117 {
118  // seconds instead of ms
119  return m_totalTime / (1000);
120 }
121 
122 void TestEntryManager::practiceStarted()
123 {
124  kDebug() << "start practice timer";
125  m_time.start();
126 }
127 
128 void TestEntryManager::practiceFinished()
129 {
130  m_totalTime = m_time.elapsed();
131  kDebug() << "stop practice timer" << m_totalTime << m_time.toString();
132 }
133 
134 int TestEntryManager::totalEntryCount()
135 {
136  return m_allTestEntries.count();
137 }
138 
139 int TestEntryManager::activeEntryCount()
140 {
141  return m_notAskedTestEntries.count() + m_currentEntries.count();
142 }
143 
144 QList<TestEntry*> TestEntryManager::allUnansweredTestEntries()
145 {
146  QList<TestEntry*> allUnansweredEntries;
147 
148  allUnansweredEntries.append(m_notAskedTestEntries);
149  allUnansweredEntries.append(m_currentEntries);
150 
151  return allUnansweredEntries;
152 }
153 
154 int TestEntryManager::statisticTotalCorrectFirstAttempt()
155 {
156  int count = 0;
157  foreach(TestEntry* entry, m_allTestEntries) {
158  if ( entry->correctAtFirstAttempt() ) {
159  count++;
160  }
161  }
162  return count;
163 }
164 
165 int TestEntryManager::statisticTotalWrong()
166 {
167  int count = 0;
168  foreach(TestEntry* entry, m_allTestEntries) {
169  if ( entry->statisticBadCount() ) {
170  count++;
171  }
172  }
173  return count;
174 }
175 
176 int TestEntryManager::statisticTotalUnanswered()
177 {
178  int count = 0;
179  foreach(TestEntry* entry, m_allTestEntries) {
180  if ( entry->statisticCount() == 0 ) {
181  count++;
182  }
183  }
184  return count;
185 }
186 
187 
188 TestEntry* TestEntryManager::getNextEntry()
189 {
190  // refill current entries
191  while ( m_currentEntries.count() < Prefs::testNumberOfEntries() &&
192  m_notAskedTestEntries.count() > 0 ) {
193  m_currentEntries.append( m_notAskedTestEntries.takeAt(0) );
194  }
195 
196  int lastEntry = m_currentEntry;
197  // return one of the current entries
198  if ( m_currentEntries.count() > 0 ) {
199  // one of the current words (by random)
200  m_currentEntry = m_randomSequence.getLong(m_currentEntries.count());
201  // do not allow to ask the same entry twice in a row
202  if ( m_currentEntries.count() > 1 ) {
203  while ( m_currentEntry == lastEntry ) {
204  m_currentEntry = m_randomSequence.getLong(m_currentEntries.count());
205  }
206  }
207 
208  kDebug() << "nextEntry: " << m_currentEntry << " = " << m_currentEntries.value(m_currentEntry)->entry()->translation(0)->text() << " (" << m_currentEntries.count() + m_notAskedTestEntries.count() << "entries remaining)";
209 
210  return m_currentEntries.value(m_currentEntry);
211  } else {
212  return 0;
213  }
214 }
215 
216 QStringList TestEntryManager::multipleChoiceAnswers(int numberChoices)
217 {
218  QStringList choices;
219  KRandomSequence randomSequence;
220  QList<KEduVocExpression*> allEntries = m_doc->lesson()->entries(KEduVocLesson::Recursive);
221  int numValidEntries = 0;
222  int count = numberChoices;
223 
224  // if the current entry has predefined multiple choice entries definied, use them first
225  QStringList predefinedChoices = m_currentEntries.at(m_currentEntry)->entry()->translation(Prefs::solutionLanguage())->multipleChoice();
226  while (!predefinedChoices.isEmpty() && count > 0) {
227  choices.append(predefinedChoices.takeAt(randomSequence.getLong(predefinedChoices.count())));
228  count--;
229  }
230 
231  // find out if we got enough valid entries to fill all the options
232  for(int i = 0; i < allEntries.count(); ++i) {
233  if(isValidMultipleChoiceAnswer(allEntries.value(i)))
234  numValidEntries++;
235  if(numValidEntries >= numberChoices)
236  break;
237  }
238 
239  // if we don't have enough valid entries, just try everything and use what we can get
240  if (numValidEntries < numberChoices) {
241  for (int i = choices.count(); i < allEntries.count(); ++i) {
242  KEduVocExpression *exp = allEntries.value(i);
243 
244  if (isValidMultipleChoiceAnswer(exp)) {
245  choices.append(exp->translation(Prefs::solutionLanguage())->text());
246  }
247  }
248  } else {
249  QList<KEduVocExpression*> exprlist;
250  while (count > 0) {
251  int nr;
252  // if there are enough non-empty fields, fill the options only with those
253  do {
254  nr = randomSequence.getLong(allEntries.count());
255  } while (!isValidMultipleChoiceAnswer(allEntries.value(nr)));
256  // append if new entry found
257  bool newex = true;
258  for (int i = 0; newex && i < exprlist.count(); i++) {
259  if (exprlist[i] == allEntries.value(nr))
260  newex = false;
261  }
262  if (newex) {
263  count--;
264  exprlist.append(allEntries.value(nr));
265  }
266  }
267 
268  for (int i = 0; i < exprlist.count(); i++) {
269  choices.append(exprlist[i]->translation(Prefs::solutionLanguage())->text());
270  }
271  }
272 
273  kDebug() << "choices:" << choices;
274  return choices;
275 }
276 
277 bool TestEntryManager::isValidMultipleChoiceAnswer(KEduVocExpression *e)
278 {
279  // entry is empty
280  if (e->translation(Prefs::solutionLanguage())->text().trimmed().isEmpty())
281  return false;
282  // entry is a synonym of the solution
283  if (e->translation(Prefs::solutionLanguage())->synonyms().contains(m_currentEntries.at(m_currentEntry)->entry()->translation(Prefs::solutionLanguage())))
284  return false;
285  // entry has the same text as the solution
286  if (e->translation(Prefs::solutionLanguage())->text().simplified() == m_currentEntries.at(m_currentEntry)->entry()->translation(Prefs::solutionLanguage())->text().simplified())
287  return false;
288  return true;
289 }
290 
TestEntry::statisticCount
int statisticCount()
Definition: testentry.cpp:49
Practice::TestEntryManager::activeEntryCount
int activeEntryCount()
The number of entries that are still to be practiced.
Definition: testentrymanager.cpp:139
Practice::TestEntryManager::statisticTotalCorrectFirstAttempt
int statisticTotalCorrectFirstAttempt()
Finish the given entry.
Definition: testentrymanager.cpp:154
testentrymanager.h
QWidget
TestEntry::setGradeTo
static void setGradeTo(int to)
Definition: testentry.cpp:34
Prefs::questionLanguage
static int questionLanguage()
Get The language that is displayed in a test.
Definition: prefs.h:1167
TestEntry::statisticGoodCount
int statisticGoodCount()
Definition: testentry.cpp:59
prefs.h
entryfilter.h
Prefs::testNumberOfEntries
static int testNumberOfEntries()
Get The number of entries that are practiced at the same time.
Definition: prefs.h:369
Practice::TestEntryManager::setDocument
void setDocument(KEduVocDocument *doc)
Definition: testentrymanager.cpp:50
Practice::TestEntryManager::getNextEntry
TestEntry * getNextEntry()
Get the next entry to show to the user.
Definition: testentrymanager.cpp:188
Practice::TestEntryManager::totalTime
int totalTime()
the time in seconds
Definition: testentrymanager.cpp:116
Practice::EntryFilter
Definition: entryfilter.h:32
Practice::TestEntryManager::multipleChoiceAnswers
QStringList multipleChoiceAnswers(int numberChoices)
Definition: testentrymanager.cpp:216
Practice::TestEntryManager::totalEntryCount
int totalEntryCount()
The number of entries in the practice.
Definition: testentrymanager.cpp:134
Practice::TestEntryManager::statisticTotalWrong
int statisticTotalWrong()
Definition: testentrymanager.cpp:165
Practice::TestEntryManager::allUnansweredTestEntries
QList< TestEntry * > allUnansweredTestEntries()
Get a list of all unanswered entries in the test.
Definition: testentrymanager.cpp:144
Practice::TestEntryManager::practiceFinished
void practiceFinished()
Definition: testentrymanager.cpp:128
TestEntry::statisticBadCount
int statisticBadCount()
Definition: testentry.cpp:54
Practice::TestEntryManager::~TestEntryManager
~TestEntryManager()
Default ctor.
Definition: testentrymanager.cpp:44
Prefs::setQuestionLanguage
static void setQuestionLanguage(int v)
Set The language that is displayed in a test.
Definition: prefs.h:1157
Practice::TestEntryManager::TestEntryManager
TestEntryManager(QWidget *parent)
Create a collection of entries to be practiced.
Definition: testentrymanager.cpp:34
Practice::TestEntryManager::practiceStarted
void practiceStarted()
Definition: testentrymanager.cpp:122
Practice::TestEntryManager::printStatistics
void printStatistics()
Puts some grades on the shell.
Definition: testentrymanager.cpp:105
Practice::TestEntryManager::removeCurrentEntryFromPractice
void removeCurrentEntryFromPractice()
Finish the currently active entry.
Definition: testentrymanager.cpp:98
Prefs::setSolutionLanguage
static void setSolutionLanguage(int v)
Set The language in which the user has to answer.
Definition: prefs.h:1176
TestEntry::correctAtFirstAttempt
bool correctAtFirstAttempt()
Definition: testentry.cpp:109
Practice::TestEntryManager::statisticTotalUnanswered
int statisticTotalUnanswered()
Definition: testentrymanager.cpp:176
TestEntry::setGradeFrom
static void setGradeFrom(int from)
Definition: testentry.cpp:39
Prefs::solutionLanguage
static int solutionLanguage()
Get The language in which the user has to answer.
Definition: prefs.h:1186
TestEntry::entry
KEduVocExpression * entry()
Definition: testentry.cpp:134
TestEntry
Definition: testentry.h:22
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:42:06 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

parley

Skip menu "parley"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal