/// <summary> /// Returns next question /// </summary> /// <param name="testData">Test session info</param> /// <returns></returns> private Question GetQuestion(TestData testData) { int[] priorityArray = GetDifficultyPriorityArray(testData.TrueDifficultyLevel); int i = 0; int nextQuestionId = -1; while (nextQuestionId == -1 && i < 10) { nextQuestionId = testData.QuestionBank.GetQuestion(priorityArray[i]); if (++i >= 10) { throw new Exception("Нет подходящих вопросов"); } } return(QuestionController.GetById(nextQuestionId)); }
public ActionResult Process(FormCollection collection) { // Geting session information int sessionId = 0; TestData testData = GetTestData(out sessionId); // If test data is bad ending survey if (testData == null) { return(RedirectToAction("End")); } // If bad question token (for example student are trying to answer question previously cached in browser) redirecting to Index (will show last generated question) if (collection["QuestionToken"] != testData.GetQuestionHash()) { return(RedirectToAction("Index")); } // Get previous question to check asnwer is correct GeneratedQuestion question = TemplateManager.Generate(testData.CurrentQuestionId, testData.TestSeed); // Remembering some nessasary data testData.ItemsTaken++; testData.TotalDifficultiesUsed += testData.CurrentQuestionDifficulty; // Calculating the amount that will change the difficulty double difficultyShift = 0.2 + (float)2 / testData.ItemsTaken; // Checking answer is correct bool answerIsCorrect = CheckAnswerIsCorrect(question, collection["Answers"]); // Saving to question information about its own statistic QuestionController.AddAttempt(testData.CurrentQuestionId, answerIsCorrect); // Adding data to 'ResultGraph' testData.AddPointToResultGraph(answerIsCorrect); // TODO: Temperory method for statistics. (Re)move testData.AddPointToRDF(); // Correcting difficulty if (answerIsCorrect) { testData.TrueDifficultyLevel += difficultyShift; if (testData.TrueDifficultyLevel > 10) { testData.TrueDifficultyLevel = 10; } testData.RightAnswersCount++; } else { testData.TrueDifficultyLevel -= difficultyShift; if (testData.TrueDifficultyLevel < 1) { testData.TrueDifficultyLevel = 1; } } // TODO: Make CONST optional. For the next programmers' generation // Checking if measurement error lower than CONST var error = testData.CalculateError(); var measure = testData.CalculateMeasure(); if (error <= 0.5) { testData.TestCompleted = true; } if (measure + error <= 1 || measure - error >= 10) { testData.TestCompleted = true; } //Check for test min length // TODO: Add some behaviors. For the next programmers' generation. For example different options for different test types. // If amount of taken question equals amount of total questions in test, mark test as completed. if (testData.ItemsTaken >= testData.MaxAmountOfQuestions) { testData.TestCompleted = true; } // TODO: Add min length to test data else if (testData.ItemsTaken < 10) { testData.TestCompleted = false; } // Selecting next question Question selectedQuestion = GetQuestion(testData); // Generates random seed, which helps to generate the same question from tamplate, if needed testData.TestSeed = TemplateManager.GetRandomSeed(); // Remembering next question parameters testData.CurrentQuestionDifficulty = selectedQuestion.Difficulty; testData.CurrentQuestionId = selectedQuestion.ID; // Saving test session SetTestData(testData, sessionId); // Continue test or end it depending on TestCompleted flag return((testData.TestCompleted) ? RedirectToAction("End") : RedirectToAction("Index")); }