public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { var words = word.Word.Split(',').Select(s => s.Trim()).ToArray(); var minCount = words.Min(t => t.Count(c => c == ' ')); if (minCount > 0 && word.AbsoluteScore < minCount * 4) { return(ExamResult.Impossible); } await chatIo.SendMessageAsync($"=====> {word.TranslationAsList} <=====\r\n" + $"Write the translation... "); var userEntry = await chatIo.WaitUserTextInputAsync(); if (string.IsNullOrEmpty(userEntry)) { return(ExamResult.Retry); } if (words.Any(t => string.Compare(userEntry.Trim(), t, StringComparison.OrdinalIgnoreCase) == 0)) { await service.RegisterSuccess(word); return(ExamResult.Passed); } //search for other translation var translationCandidate = await _dictionaryService.GetAllTranslationWords(userEntry.ToLower()); if (translationCandidate.Any(t1 => word.GetTranslations().Any(t2 => string.CompareOrdinal(t1.Trim(), t2.Trim()) == 0))) { //translation is correct, but for other word await chatIo.SendMessageAsync( $"the translation was correct, but the question was about the word '{word.Word} - {word.TranslationAsList}'\r\nlet's try again"); return(ExamResult.Retry); } var translates = string.Join(",", translationCandidate); if (!string.IsNullOrWhiteSpace(translates)) { await chatIo.SendMessageAsync($"'{userEntry}' translates as {translates}"); } await chatIo.SendMessageAsync("The right translation was: " + word.Word); await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { if (!word.Phrases.Any()) { return(ExamResult.Impossible); } var phrase = word.GetRandomExample(); var replaced = phrase.OriginPhrase.Replace(phrase.OriginWord, "..."); if (replaced == phrase.OriginPhrase) { return(ExamResult.Impossible); } var sb = new StringBuilder(); sb.AppendLine($"\"{phrase.TranslatedPhrase}\""); sb.AppendLine(); sb.AppendLine($" translated as "); sb.AppendLine(); sb.AppendLine($"\"{replaced}\""); sb.AppendLine($"Choose missing word..."); var variants = examList.Randomize().Select(e => e.Word).ToArray(); var _ = chatIo.SendMessageAsync(sb.ToString(), InlineButtons.CreateVariants(variants)); var choice = await chatIo.TryWaitInlineIntKeyboardInput(); if (choice == null) { return(ExamResult.Retry); } if (variants[choice.Value] == word.Word) { await service.RegisterSuccess(word); return(ExamResult.Passed); } await chatIo.SendMessageAsync($"Origin was: \"{phrase.OriginPhrase}\""); await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { if (!word.Phrases.Any()) { return(ExamResult.Impossible); } var phrase = word.GetRandomExample(); var replaced = phrase.TranslatedPhrase.Replace(phrase.TranslatedWord, "..."); if (replaced == phrase.TranslatedPhrase) { return(ExamResult.Impossible); } var sb = new StringBuilder(); sb.AppendLine($"\"{phrase.OriginPhrase}\""); sb.AppendLine($" translated as "); sb.AppendLine($"\"{replaced}\""); sb.AppendLine(); sb.AppendLine($"Enter missing word: "); await chatIo.SendMessageAsync(sb.ToString()); while (true) { var enter = await chatIo.WaitUserTextInputAsync(); if (string.IsNullOrWhiteSpace(enter)) { continue; } if (string.Compare(phrase.OriginWord, enter.Trim(), StringComparison.OrdinalIgnoreCase) == 0) { await service.RegisterSuccess(word); return(ExamResult.Passed); } await chatIo.SendMessageAsync($"Origin phrase was \"{phrase.TranslatedPhrase}\""); await service.RegisterFailure(word); return(ExamResult.Failed); } }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { var variants = examList.Randomize().SelectMany(e => e.GetTranslations()).ToArray(); var msg = $"=====> {word.Word} <=====\r\n" + $"Choose the translation"; await chatIo.SendMessageAsync(msg, InlineButtons.CreateVariants(variants)); var choice = await chatIo.TryWaitInlineIntKeyboardInput(); if (choice == null) { return(ExamResult.Retry); } if (word.GetTranslations().Contains(variants[choice.Value])) { await service.RegisterSuccess(word); return(ExamResult.Passed); } await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { var translations = word.GetTranslations().ToArray(); var minCount = translations.Min(t => t.Count(c => c == ' ')); if (minCount > 0 && word.AbsoluteScore < minCount * 4) { return(ExamResult.Impossible); } await chatIo.SendMessageAsync($"=====> {word.Word} <=====\r\n" + $"Write the translation... "); var translation = await chatIo.WaitUserTextInputAsync(); if (string.IsNullOrEmpty(translation)) { return(ExamResult.Retry); } if (translations.Any(t => string.Compare(translation.Trim(), t, StringComparison.OrdinalIgnoreCase) == 0)) { await service.RegisterSuccess(word); return(ExamResult.Passed); } var allMeaningsOfWord = await _dictionaryService.GetAllTranslationWords(word.Word); if (allMeaningsOfWord .Any(t => string.Compare(translation, t, StringComparison.OrdinalIgnoreCase) == 0)) { await chatIo.SendMessageAsync( $"Chosen translation is out of scope (but it is correct). Expected translations are: " + word.TranslationAsList); return(ExamResult.Impossible); } await chatIo.SendMessageAsync("The translation was: " + word.TranslationAsList); await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { if (!word.HasAnyPhrases) { return(ExamResult.Impossible); } var targetPhrase = word.GetRandomExample(); string shuffled; while (true) { var wordsInExample = targetPhrase.OriginWords; if (wordsInExample.Length < 2) { return(ExamResult.Impossible); } shuffled = string.Join(" ", wordsInExample.Randomize()); if (shuffled != targetPhrase.OriginPhrase) { break; } } await chatIo.SendMessageAsync("Words in phrase are shuffled. Write them in correct order:\r\n'" + shuffled + "'"); var entry = await chatIo.WaitUserTextInputAsync(); entry = entry.Trim(); if (string.Compare(targetPhrase.OriginPhrase, entry.Trim(), StringComparison.OrdinalIgnoreCase) == 0) { await service.RegisterSuccess(word); return(ExamResult.Passed); } await chatIo.SendMessageAsync($"Original phrase was: '{targetPhrase.OriginPhrase}'"); await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task <ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { var msg = $"=====> {word.Word} <=====\r\n" + $"Do you know the translation?"; var _ = chatIo.SendMessageAsync(msg, new InlineKeyboardButton() { CallbackData = "1", Text = "See the translation" }); await chatIo.WaitInlineIntKeyboardInput(); _ = chatIo.SendMessageAsync($"Translation is \r\n" + $"{word.TranslationAsList}\r\n" + $" Did you guess?", new InlineKeyboardButton { CallbackData = "1", Text = "Yes" }, new InlineKeyboardButton { CallbackData = "0", Text = "No" }); var choice = await chatIo.WaitInlineIntKeyboardInput(); if (choice == 1) { await service.RegisterSuccess(word); return(ExamResult.Passed); } else { await service.RegisterFailure(word); return(ExamResult.Failed); } }
public async Task Run() { try { await Initialize(); (string Command, IBotCommandHandler CommandHandler)? mainMenuCommandOrNull = null; while (true) { try { //run main scenario or mainMenuCommand await HandleMainScenario(mainMenuCommandOrNull); mainMenuCommandOrNull = null; } catch (UserAFKException) { return; } catch (ProcessInterruptedWithMenuCommand e) { //main scenario may be interrupted with main menu command mainMenuCommandOrNull = (e.Command, e.CommandHandler); } catch (Exception e) { Botlog.WriteError(ChatIo.ChatId.Identifier, $"{ChatIo.ChatId.Username} exception: {e}", true); await ChatIo.SendMessageAsync(Chat.Texts.OopsSomethingGoesWrong); throw; } } } catch (Exception e) { Botlog.WriteError(ChatIo?.ChatId?.Identifier, $"Fatal on run: {e}", true); throw; } }
public async Task <ExamResult> Pass( ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { if (!word.HasAnyPhrases) { return(ExamResult.Impossible); } var targetPhrase = word.GetRandomExample(); var otherExamples = examList .SelectMany(e => e.Phrases) .Where(p => p != targetPhrase) .Take(8).ToArray(); if (!otherExamples.Any()) { return(ExamResult.Impossible); } var variants = otherExamples .Append(targetPhrase) .Randomize() .Select(e => e.TranslatedPhrase) .ToArray(); var msg = $"=====> {targetPhrase.OriginPhrase} <=====\r\n" + $"Choose the translation"; await chatIo.SendMessageAsync(msg, InlineButtons.CreateVariants(variants)); var choice = await chatIo.TryWaitInlineIntKeyboardInput(); if (choice == null) { return(ExamResult.Retry); } if (variants[choice.Value] == targetPhrase.TranslatedPhrase) { await service.RegisterSuccess(word); return(ExamResult.Passed); } await service.RegisterFailure(word); return(ExamResult.Failed); }
public async Task<ExamResult> Pass(ChatIO chatIo, UsersWordsService service, UserWordModel word, UserWordModel[] examList) { if (!word.Phrases.Any()) return ExamResult.Impossible; var targetPhrase = word.GetRandomExample(); var other = examList.SelectMany(e => e.Phrases) .Where(p => !string.IsNullOrWhiteSpace(p?.OriginPhrase) && p!= targetPhrase) .Take(8).ToArray(); if(!other.Any()) return ExamResult.Impossible; var variants = other .Append(targetPhrase) .Randomize() .Select(e => e.OriginPhrase) .ToArray(); var msg = $"=====> {targetPhrase.TranslatedPhrase} <=====\r\n" + $"Choose the translation"; await chatIo.SendMessageAsync(msg, variants.Select((v, i) => new InlineKeyboardButton { CallbackData = i.ToString(), Text = v }).ToArray()); var choice = await chatIo.TryWaitInlineIntKeyboardInput(); if (choice == null) return ExamResult.Retry; if (variants[choice.Value] == targetPhrase.OriginPhrase) { await service.RegisterSuccess(word); return ExamResult.Passed; } await service.RegisterFailure(word); return ExamResult.Failed; }
private async Task <bool> EnterSingleWordAsync(User user, string?word = null) { if (word == null) { await _chatIo.SendMessageAsync("Enter english word", new InlineKeyboardButton { CallbackData = "/start", Text = "Cancel" }); while (true) { var input = await _chatIo.WaitUserInputAsync(); if (input.CallbackQuery != null && input.CallbackQuery.Data == "/start") { throw new ProcessInterruptedWithMenuCommand("/start"); } if (!string.IsNullOrEmpty(input.Message?.Text)) { word = input.Message.Text; break; } } } //find word in local dictionary(if not, find it in Ya dictionary) var translations = await _addWordService.FindInDictionaryWithoutExamples(word); if (!translations.Any()) { translations = await _addWordService.TranslateAndAddToDictionary(word); } if (translations?.Any() != true) { await _chatIo.SendMessageAsync("No translations found. Check the word and try again"); return(true); } await _chatIo.SendMessageAsync($"Choose translation for '{word}'", InlineButtons.CreateVariantsWithCancel(translations.Select(t => t.RuWord))); await _addWordService.RegistrateTranslationRequest(user); while (true) { var input = await _chatIo.TryWaitInlineIntKeyboardInput(); if (!input.HasValue) { return(false); } if (input !.Value < 0 || input.Value >= translations.Count) { continue; } var selected = translations[input.Value]; await _addWordService.AddWordsToUser(user, new[] { selected }); if (selected.Examples.Count > 0) { await _chatIo.SendMessageAsync($"Saved. Examples: {selected.Examples.Count}"); } else { await _chatIo.SendMessageAsync($"Saved."); } return(true); } }
public async Task EnterAsync(User user) { if (!await _usersWordsService.HasWords(user)) { await _chatIo.SendMessageAsync("You need to add some more words before examination"); return; } //Randomization and jobs //if (RandomTools.Rnd.Next() % 30 == 0) // await _usersWordsService.AddMutualPhrasesToVocabAsync(user, 10); // else var startupScoreUpdate = _usersWordsService.UpdateCurrentScore(user, _examSettings.MaxLearningWordsCountInOneExam * 2); var typing = _chatIo.SendTyping(); var c = Random.RandomIn(_examSettings.MinLearningWordsCountInOneExam, _examSettings.MaxLearningWordsCountInOneExam); await startupScoreUpdate; await typing; var learningWords = await _usersWordsService.GetWordsForLearningWithPhrasesAsync(user, c, 3); var learningWordsCount = learningWords.Length; if (learningWords.Average(w => w.AbsoluteScore) <= 4) { var sb = new StringBuilder("Examination\r\n"); foreach (var pairModel in learningWords.Randomize()) { sb.AppendLine($"{pairModel.Word}\t\t:{pairModel.TranslationAsList}"); } await _chatIo.SendMessageAsync(sb.ToString(), new InlineKeyboardButton { CallbackData = "/startExamination", Text = "Start" }, new InlineKeyboardButton { CallbackData = "/start", Text = "Cancel", }); var userInput = await _chatIo.WaitInlineKeyboardInput(); if (userInput != "/startExamination") { return; } } var started = DateTime.Now; var learningAndAdvancedWords = await _usersWordsService.AppendAdvancedWordsToExamList(user, learningWords, _examSettings); var questionsCount = 0; var questionsPassed = 0; var i = 0; ExamResult?lastExamResult = null; foreach (var word in learningAndAdvancedWords) { var allLearningWordsWereShowedAtLeastOneTime = i < learningWordsCount; var exam = QuestionSelector.Singletone.GetNextQuestionFor(allLearningWordsWereShowedAtLeastOneTime, word); i++; var retryFlag = false; do { retryFlag = false; var sw = Stopwatch.StartNew(); var questionMetric = new QuestionMetric(word, exam.Name); var learnList = learningWords; if (!learningWords.Contains(word)) { learnList = learningWords.Append(word).ToArray(); } if (i > 1 && exam.NeedClearScreen && lastExamResult != ExamResult.Impossible) { await WriteDontPeakMessage(); if (lastExamResult == ExamResult.Passed) { await WritePassed(); } } var result = await exam.Pass(_chatIo, _usersWordsService, word, learnList); sw.Stop(); questionMetric.ElaspedMs = (int)sw.ElapsedMilliseconds; switch (result) { case ExamResult.Impossible: exam = QuestionSelector.Singletone.GetNextQuestionFor(i == 0, word); retryFlag = true; break; case ExamResult.Passed: await WritePassed(); Botlog.SaveQuestionMetric(questionMetric); questionsCount++; questionsPassed++; break; case ExamResult.Failed: await WriteFailed(); questionMetric.Result = 0; Botlog.SaveQuestionMetric(questionMetric); questionsCount++; break; case ExamResult.Retry: retryFlag = true; break; case ExamResult.Exit: return; } lastExamResult = result; } while (retryFlag); Botlog.RegisterExamAsync(user.TelegramId, started, questionsCount, questionsPassed); } var finializeScoreUpdateTask = _usersWordsService.UpdateCurrentScore(user, 10); var doneMessage = new StringBuilder($"Learning done: {questionsPassed}/{questionsCount}\r\n"); foreach (var pairModel in learningAndAdvancedWords.Distinct()) { doneMessage.Append(pairModel.Word + " - " + pairModel.TranslationAsList + " (" + pairModel.AbsoluteScore + ")\r\n"); } await _chatIo.SendMessageAsync(doneMessage.ToString()); }