예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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;
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
        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;
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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());
        }