/// <summary> /// Creates the learn log entry. /// </summary> /// <param name="learnLog">The learn log.</param> /// <remarks>Documented by Dev10, 2009-01-11</remarks> public void CreateLearnLogEntry(LearnLogStruct learnLog) { bool answeredCardCorrect = false; if (learnLog.MoveType != MoveType.Manual) { if (learnLog.NewBox > 1) answeredCardCorrect = true; } using (SqlCeCommand cmd = MSSQLCEConn.CreateCommand(Parent.CurrentUser)) { cmd.CommandText = "INSERT INTO LearnLog (session_id, user_id, lm_id, cards_id, old_box, new_box, timestamp, duration, learn_mode, move_type, answer, direction, case_sensitive, ignore_accent_chars, correct_on_the_fly, percentage_known, percentage_required) "; cmd.CommandText += "VALUES(@sid, @uid, @lmid, @cid, @obox, @nbox, @ts, @dur, @lmode, @mtype, @answ, @dir, @csen,@iach,@cotf, @pknown, @preq); "; if (learnLog.MoveType != MoveType.Manual && answeredCardCorrect) cmd.CommandText += "UPDATE LearningSessions SET sum_right=sum_right + 1 WHERE id=@sid AND user_id=@uid AND lm_id=@lmid; "; else if (learnLog.MoveType != MoveType.Manual && !answeredCardCorrect) cmd.CommandText += "UPDATE LearningSessions SET sum_wrong=sum_wrong + 1 WHERE id=@sid AND user_id=@uid AND lm_id=@lmid; "; string newBoxContent = string.Empty; string oldBoxContent = string.Empty; if (learnLog.NewBox.Value > 0) newBoxContent = "box" + learnLog.NewBox.Value.ToString() + "_content"; else newBoxContent = "pool_content"; if (learnLog.OldBox.Value > 0) oldBoxContent = "box" + learnLog.OldBox.Value.ToString() + "_content"; else oldBoxContent = "pool_content"; if (learnLog.NewBox.Value != learnLog.OldBox.Value) cmd.CommandText += "UPDATE LearningSessions SET " + newBoxContent + "=" + newBoxContent + " + 1, " + oldBoxContent + "=" + oldBoxContent + " - 1 WHERE id=@sid AND user_id=@uid AND lm_id=@lmid; "; cmd.Parameters.Add("@sid", learnLog.SessionID.Value); cmd.Parameters.Add("@uid", Parent.CurrentUser.Id); cmd.Parameters.Add("@lmid", Parent.CurrentUser.ConnectionString.LmId); cmd.Parameters.Add("@cid", learnLog.CardsID.Value); cmd.Parameters.Add("@obox", learnLog.OldBox.Value); cmd.Parameters.Add("@nbox", learnLog.NewBox.Value); cmd.Parameters.Add("@ts", learnLog.TimeStamp.Value); cmd.Parameters.Add("@dur", learnLog.Duration.Value); cmd.Parameters.Add("@lmode", learnLog.LearnMode.Value.ToString()); cmd.Parameters.Add("@mtype", learnLog.MoveType.Value.ToString()); cmd.Parameters.Add("@answ", learnLog.Answer); cmd.Parameters.Add("@dir", learnLog.Direction.Value.ToString()); cmd.Parameters.Add("@csen", learnLog.CaseSensitive); cmd.Parameters.Add("@iach", learnLog.IgnoreAccentChars); cmd.Parameters.Add("@cotf", learnLog.CorrectOnTheFly); cmd.Parameters.Add("@pknown", learnLog.PercentageKnown); cmd.Parameters.Add("@preq", learnLog.PercentageRequired); MSSQLCEConn.ExecuteNonQuery(cmd); } //delete caches Parent.CurrentUser.Cache.Uncache(ObjectLifetimeIdentifier.GetIdentifier(CacheObject.StatisticWrongCards, learnLog.SessionID.Value)); Parent.CurrentUser.Cache.Uncache(ObjectLifetimeIdentifier.GetIdentifier(CacheObject.StatisticCorrectCards, learnLog.SessionID.Value)); Parent.CurrentUser.Cache.Uncache(ObjectLifetimeIdentifier.GetIdentifier(CacheObject.StatisticContentOfBoxes, learnLog.SessionID.Value)); }
/// <summary> /// Creates a learn log entry. /// </summary> /// <param name="learnLog">A learn log struct.</param> /// <remarks>Documented by Dev08, 2008-09-05</remarks> public void CreateLearnLogEntry(LearnLogStruct learnLog) { bool answeredCardCorrect = false; if (learnLog.MoveType != MoveType.Manual) { if (learnLog.NewBox > 1) answeredCardCorrect = true; } using (NpgsqlConnection con = PostgreSQLConn.CreateConnection(Parent.CurrentUser)) { using (NpgsqlCommand cmd = con.CreateCommand()) { cmd.CommandText = "INSERT INTO \"LearnLog\" (session_id, user_id, lm_id, cards_id, old_box, new_box, timestamp, duration, learn_mode, move_type, answer, direction, case_sensitive,ignore_accent_chars, correct_on_the_fly, percentage_known, percentage_required) "; cmd.CommandText += " VALUES(:sid, :uid, :lmid, :cid, :obox, :nbox, :ts, :dur, :lmode, :mtype, :answ, :dir, :csen,:iach, :cotf, :pknown, :preq); "; if (learnLog.MoveType != MoveType.Manual && answeredCardCorrect) cmd.CommandText += "UPDATE \"LearningSessions\" SET sum_right=sum_right + 1 WHERE id=:sid AND user_id=:uid AND lm_id=:lmid; "; else if (learnLog.MoveType != MoveType.Manual && !answeredCardCorrect) cmd.CommandText += "UPDATE \"LearningSessions\" SET sum_wrong=sum_wrong + 1 WHERE id=:sid AND user_id=:uid AND lm_id=:lmid; "; string newBoxContent = string.Empty; string oldBoxContent = string.Empty; if (learnLog.NewBox.Value > 0) newBoxContent = "box" + learnLog.NewBox.Value.ToString() + "_content"; else newBoxContent = "pool_content"; if (learnLog.OldBox.Value > 0) oldBoxContent = "box" + learnLog.OldBox.Value.ToString() + "_content"; else oldBoxContent = "pool_content"; if (learnLog.NewBox.Value != learnLog.OldBox.Value) cmd.CommandText += "UPDATE \"LearningSessions\" SET " + newBoxContent + "=" + newBoxContent + " + 1, " + oldBoxContent + "=" + oldBoxContent + " - 1 WHERE id=:sid AND user_id=:uid AND lm_id=:lmid; "; cmd.Parameters.Add("sid", learnLog.SessionID.Value); cmd.Parameters.Add("uid", Parent.CurrentUser.Id); cmd.Parameters.Add("lmid", Parent.CurrentUser.ConnectionString.LmId); cmd.Parameters.Add("cid", learnLog.CardsID.Value); cmd.Parameters.Add("obox", learnLog.OldBox.Value); cmd.Parameters.Add("nbox", learnLog.NewBox.Value); cmd.Parameters.Add("ts", (NpgsqlTypes.NpgsqlTimeStamp)learnLog.TimeStamp.Value); cmd.Parameters.Add("dur", learnLog.Duration.Value); cmd.Parameters.Add("lmode", learnLog.LearnMode.Value.ToString()); cmd.Parameters.Add("mtype", learnLog.MoveType.Value.ToString()); cmd.Parameters.Add("answ", learnLog.Answer); cmd.Parameters.Add("dir", learnLog.Direction.Value.ToString()); cmd.Parameters.Add("csen", learnLog.CaseSensitive); cmd.Parameters.Add("iach", learnLog.CaseSensitive); cmd.Parameters.Add("cotf", learnLog.CorrectOnTheFly); cmd.Parameters.Add("pknown", learnLog.PercentageKnown); cmd.Parameters.Add("preq", learnLog.PercentageRequired); PostgreSQLConn.ExecuteNonQuery(cmd, Parent.CurrentUser); } } }
/// <summary> /// Sets the card values. /// </summary> /// <param name="card">The card.</param> /// <remarks>Documented by Dev05, 2007-10-12</remarks> private void SetCardValues(ICard card) { card.Answer.ClearWords(); card.Question.ClearWords(); card.Answer.AddWords(GetWord(Side.Answer).Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)); card.Question.AddWords(GetWord(Side.Question).Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)); card.AnswerDistractors.ClearWords(); card.QuestionDistractors.ClearWords(); card.AnswerDistractors.AddWords(GetDistractors(Side.Answer).ToArray()); card.QuestionDistractors.AddWords(GetDistractors(Side.Question).ToArray()); card.AnswerExample.ClearWords(); card.AnswerExample.AddWord(card.AnswerExample.CreateWord(textBoxAnswerExample.Text, WordType.Sentence, false)); card.QuestionExample.ClearWords(); card.QuestionExample.AddWord(card.QuestionExample.CreateWord(textBoxQuestionExample.Text, WordType.Sentence, false)); if (comboBoxChapter.SelectedItem != null && comboBoxChapter.SelectedItem is IChapter) card.Chapter = ((IChapter)comboBoxChapter.SelectedItem).Id; card.Active = checkBoxActive.Checked; card.ClearAllMedia(false); try { this.Parent.Enabled = false; //ML-2413, maintain doesn't block user inputs while loading stuff into db //currently only the DB can show a progress bar card.CreateMediaProgressChanged += new StatusMessageEventHandler(card_CreateMediaProgressChanged); statusDialog = new LoadStatusMessage(Resources.CARDEDIT_LOADING_MEDIA_TO_DB, 100, dictionary.IsDB); if (!(card is DAL.Preview.PreviewCard)) statusDialog.Show(); statusDialog.SetProgress(0); //Image if (pictureBoxAnswer.Tag as IImage != null) { if (checkBoxResizeAnswer.Checked) ResizePicture(pictureBoxAnswer); card.AddMedia(pictureBoxAnswer.Tag as IMedia, Side.Answer); } if (pictureBoxQuestion.Tag as IImage != null) { if (checkBoxResizeQuestion.Checked) ResizePicture(pictureBoxQuestion); IMedia media = pictureBoxQuestion.Tag as IMedia; media = card.AddMedia(media, Side.Question); if (checkBoxSamePicture.Checked) card.AddMedia(media, Side.Answer); } //Audio if (buttonAnswerAudio.Tag as IAudio != null) card.AddMedia(buttonAnswerAudio.Tag as IMedia, Side.Answer); if (buttonAnswerExampleAudio.Tag as IAudio != null) card.AddMedia(buttonAnswerExampleAudio.Tag as IMedia, Side.Answer); if (buttonQuestionAudio.Tag as IAudio != null) card.AddMedia(buttonQuestionAudio.Tag as IMedia, Side.Question); if (buttonQuestionExampleAudio.Tag as IAudio != null) card.AddMedia(buttonQuestionExampleAudio.Tag as IMedia, Side.Question); //video if (buttonAnswerVideo.Tag as IVideo != null) card.AddMedia(buttonAnswerVideo.Tag as IMedia, Side.Answer); if (buttonQuestionVideo.Tag as IVideo != null) card.AddMedia(buttonQuestionVideo.Tag as IMedia, Side.Question); if (card.Active) { int oldBox = card.Box; card.Box = comboBoxCardBox.SelectedIndex; int newBox = card.Box; if (oldBox != newBox) { LearnLogStruct lls = new LearnLogStruct(); lls.CardsID = card.Id; lls.SessionID = Log.LastSessionID; lls.MoveType = MoveType.Manual; lls.OldBox = oldBox; lls.NewBox = newBox; //Dummy values: lls.TimeStamp = DateTime.Now; lls.Duration = 0; lls.CaseSensitive = false; lls.CorrectOnTheFly = false; lls.Direction = EQueryDirection.Question2Answer; lls.LearnMode = EQueryType.Word; Log.CreateLearnLogEntry(lls, dictionary.DictionaryDAL.Parent); } } CardID = card.Id; Modified = false; } catch { throw; } finally { this.Parent.Enabled = true; card.CreateMediaProgressChanged -= new StatusMessageEventHandler(card_CreateMediaProgressChanged); if (statusDialog != null) { statusDialog.Close(); statusDialog = null; } } }
/// <summary> /// Creates the learn log entry. /// </summary> /// <param name="learnLogStruct">The learn log struct.</param> /// <param name="parent">The parent.</param> /// <remarks>Documented by Dev08, 2008-09-05</remarks> public static void CreateLearnLogEntry(LearnLogStruct learnLogStruct, ParentClass parent) { if (lastSessionId < 0) //Only write if there is a valid userSession return; if (parent.CurrentUser.ConnectionString.Typ == DatabaseType.Xml) return; else { try { lock (logQueue) { logQueue.Enqueue(learnLogStruct); Monitor.Pulse(logQueue); } } catch (Exception ex) { Trace.WriteLine("Error writing log: " + ex.Message); } } }
public void IStatisticsLogAndSessionTest() { TestInfrastructure.DebugLineStart(TestContext); if (TestInfrastructure.IsActive(TestContext)) { using (IDictionary target = TestInfrastructure.GetLMConnection(TestContext, TestInfrastructure.GetAdminUser)) //Learning { if (target.Parent.CurrentUser.ConnectionString.Typ == DatabaseType.Xml) return; ICardsTests.FillDummyDic(target); Log.OpenUserSession(target.Id, target.Parent); for (int i = 0; i < 10; i++) { LearnLogStruct lls = new LearnLogStruct(); lls.SessionID = Log.LastSessionID; lls.CardsID = target.Cards.Cards[i].Id; lls.Answer = "testAnswer " + i; lls.CaseSensitive = i % 2 == 0 ? true : false; lls.CorrectOnTheFly = i % 2 == 0 ? true : false; lls.Direction = EQueryDirection.Mixed; lls.Duration = new TimeSpan(0, 0, 50).Ticks; lls.LearnMode = EQueryType.Word; lls.MoveType = i % 4 == 0 ? MoveType.AutoPromote : MoveType.AutoDemote; if (lls.MoveType == MoveType.AutoPromote) //promote { if (target.Cards.Cards[i].Box == 10) lls.NewBox = 10; else if (target.Cards.Cards[i].Box == 0) lls.NewBox = 2; else lls.NewBox = target.Cards.Cards[i].Box + 1; } else //demote lls.NewBox = 1; lls.OldBox = target.Cards.Cards[i].Box; lls.PercentageKnown = 100; lls.PercentageRequired = 50; lls.TimeStamp = DateTime.Now; Thread.Sleep(100); Log.CreateLearnLogEntry(lls, target.Parent); } Log.CloseUserSession(target.Parent); Thread.Sleep(250); Assert.AreEqual(1, target.Statistics.Count, "Dictionary.Statistics should contain ONE entry"); Assert.AreEqual(3, target.Statistics[0].Right, "Dictionary.Statistics[0].Right should contain the number 3."); Assert.AreEqual(7, target.Statistics[0].Wrong, "Dictionary.Statistics[0].Wrong should contain the number 7."); } } }
/// <summary> /// Handles the StackChanged event of the CardStack control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks>Documented by Dev08, 2008-09-11</remarks> void CardStack_StackChanged(object sender, EventArgs e) { //save log entry if (this.CardStack.Count > 0) { StackCard card = this.CardStack.Peek(); LearnLogStruct lls = new LearnLogStruct(); lls.CardsID = card.Card.Id; lls.SessionID = Log.LastSessionID; lls.Answer = card.UserAnswer; lls.CaseSensitive = card.ParentDictionary.Settings.CaseSensitive; lls.IgnoreAccentChars = card.ParentDictionary.Settings.IgnoreAccentChars; lls.CorrectOnTheFly = card.ParentDictionary.Settings.CorrectOnTheFly; lls.Direction = card.QueryDirection; lls.Duration = ((TimeSpan)(DateTime.Now.Subtract(card.CardAsked))).Seconds; lls.NewBox = card.NewBox; lls.OldBox = card.OldBox; lls.TimeStamp = DateTime.Now; //PercentageRequired, PercentageKnown if (!card.ParentDictionary.Settings.SelfAssessment.Value) { int synonyms = 0; int required = 0; if (card.QueryDirection == EQueryDirection.Question2Answer) synonyms = card.Card.Answer.Words.Count; else synonyms = card.Card.Question.Words.Count; if (synonyms != 0) { if (card.ParentDictionary.Settings.GradeSynonyms.AllKnown.Value) //All synonyms have to be known required = 100; else if (card.ParentDictionary.Settings.GradeSynonyms.FirstKnown.Value || card.ParentDictionary.Settings.GradeSynonyms.OneKnown.Value) //the first or only one synonym have to be known required = (int)(100.0 / synonyms); else if (card.ParentDictionary.Settings.GradeSynonyms.Prompt.Value) required = 100; else if (card.ParentDictionary.Settings.GradeSynonyms.HalfKnown.Value) required = 50; //MultipleChoice if (card.ParentDictionary.LearnMode == LearnModes.MultipleChoice) { lls.PercentageRequired = 100; lls.PercentageKnown = (card.Result == AnswerResult.Correct) ? 100 : 0; } else { lls.PercentageRequired = required; lls.PercentageKnown = (int)(100.0 * card.CorrectSynonyms / synonyms); } } } //LearnMode if (card.ParentDictionary.LearnMode == LearnModes.ImageRecognition) lls.LearnMode = EQueryType.ImageRecognition; else if (card.ParentDictionary.LearnMode == LearnModes.ListeningComprehension) lls.LearnMode = EQueryType.ListeningComprehension; else if (card.ParentDictionary.LearnMode == LearnModes.MultipleChoice) lls.LearnMode = EQueryType.MultipleChoice; else if (card.ParentDictionary.LearnMode == LearnModes.Sentence) lls.LearnMode = EQueryType.Sentences; else if (card.ParentDictionary.LearnMode == LearnModes.Word) lls.LearnMode = EQueryType.Word; //MoveType if (card.ParentDictionary.Settings.SelfAssessment.Value) { if (card.Promoted) lls.MoveType = MoveType.ManualPromote; else lls.MoveType = MoveType.ManualDemote; } else { if (card.Promoted) { if (card.CanceledDemote) lls.MoveType = MoveType.CanceledDemote; else lls.MoveType = MoveType.AutoPromote; } else lls.MoveType = MoveType.AutoDemote; } //Save Logging Entry to DB Log.CreateLearnLogEntry(lls, Dictionary.DictionaryDAL.Parent); } }
/// <summary> /// Changes the card boxes. /// </summary> /// <param name="cards">The cards.</param> /// <param name="newBox">The new box.</param> /// <remarks>Documented by Dev02, 2008-01-16</remarks> internal void ChangeCardBoxes(List<ICard> cards, int newBox) { foreach (ICard card in cards) { if (card.Box != newBox && newBox >= -1 && newBox < dictionary.Boxes.Count) { LearnLogStruct lls = new LearnLogStruct(); lls.CardsID = card.Id; lls.SessionID = Log.LastSessionID; lls.MoveType = MoveType.Manual; lls.OldBox = dictionary.Cards.GetCardByID(card.Id).BaseCard.Box; lls.NewBox = newBox; //Dummy values: lls.TimeStamp = DateTime.Now; lls.Duration = 0; lls.CaseSensitive = false; lls.CorrectOnTheFly = false; lls.Direction = EQueryDirection.Question2Answer; lls.LearnMode = EQueryType.Word; Log.CreateLearnLogEntry(lls, dictionary.DictionaryDAL.Parent); dictionary.Cards.GetCardByID(card.Id).BaseCard.Box = newBox; CardRefresh(card.Id); } } }