/// <summary> /// Returns the actual question that was solved on a given submission. /// </summary> public async Task <Question> ResolveSolvedQuestionAsync( UserQuestionSubmission submission) { // For normal questions, the unsolved question is the same as // all solved questions (so we ignore the submission). return(await ResolveUnsolvedQuestionAsync()); }
/// <summary> /// Returns a mock QuestionResolver. /// </summary> private IQuestionResolverFactory GetMockQuestionResolverFactory( UserQuestionDataStore store, Question resolvedQuestion = null, UserQuestionSubmission submission = null) { var questionResolverFactory = new Mock <IQuestionResolverFactory>(); var userQuestionData = store.GetUserQuestionData ( store.GetLoadedAssignmentQuestionIds()[0] ); if (submission != null) { questionResolverFactory .Setup ( m => m .CreateQuestionResolver(userQuestionData) .ResolveSolvedQuestionAsync(submission) ).ReturnsAsync(resolvedQuestion); } else { questionResolverFactory .Setup ( m => m .CreateQuestionResolver(userQuestionData) .ResolveUnsolvedQuestionAsync() ).ReturnsAsync(resolvedQuestion); } return(questionResolverFactory.Object); }
/// <summary> /// Returns the percentage deduction for lateness. /// </summary> private double GetLateDeduction( UserQuestionSubmission submission, DateTime?dueDate) { if (!dueDate.HasValue || submission.DateSubmitted <= dueDate) { return(0.0); } var daysLate = (int)Math.Ceiling ( (submission.DateSubmitted - dueDate.Value).TotalDays ); var classroom = submission.UserQuestionData .AssignmentQuestion .Assignment .Classroom; return(Math.Min ( daysLate * classroom.DailyLatenessDeduction, classroom.MaxLatenessDeduction )); }
/// <summary> /// Resolves the question corresponding to the given UserQuestionSubmission. /// </summary> private async Task <Question> ResolveSolvedQuestionAsync( UserQuestionData userQuestionData, UserQuestionSubmission userQuestionSubmission) { return(await _questionResolverFactory .CreateQuestionResolver(userQuestionData) .ResolveSolvedQuestionAsync(userQuestionSubmission)); }
/// <summary> /// Constructor. /// </summary> public ScoredSubmission( UserQuestionSubmission submission, double score, bool isLate) { Submission = submission; Score = score; Status = new SubmissionStatus(Completion.Completed, isLate); }
/// <summary> /// Returns the score for a submission. /// </summary> private double GetSubmissionScore( UserQuestionSubmission submission, DateTime?assignmentDueDate, bool withLateness) { return(_questionScoreCalculator.GetSubmissionScore ( submission, assignmentDueDate ?? DateTime.MaxValue, submission.UserQuestionData.AssignmentQuestion.Points, withLateness )); }
/// <summary> /// Returns the score of the submission. /// </summary> public double GetSubmissionScore( UserQuestionSubmission submission, DateTime?dueDate, double questionPoints, bool withLateness) { var score = submission.Score * questionPoints; if (withLateness) { score *= (1 - GetLateDeduction(submission, dueDate)); } return(Math.Round(score, 2)); }
/// <summary> /// Validates that a complete submission was retrieved from the database. /// </summary> private bool ValidateSubmission( UserQuestionSubmission submission, string questionName, string userName, double score, DateTime dateSubmitted) { return(submission.UserQuestionData != null && submission.UserQuestionData.AssignmentQuestion != null && submission.UserQuestionData.User != null && submission.UserQuestionData.AssignmentQuestion.Name == questionName && submission.UserQuestionData.User.UserName == userName && submission.Score == score && submission.DateSubmitted == dateSubmitted); }
/// <summary> /// Grades the submission. /// </summary> private async Task <ScoredQuestionResult> GradeSubmission( QuestionSubmission submission, Question resolvedQuestion, UserQuestionData userQuestionData, UserQuestionStatus userQuestionStatus, DateTime submissionDate) { if (!userQuestionStatus.AllowNewAttempt) { throw new InvalidOperationException("No attempts remaining."); } var scoredQuestionResult = await GradeQuestionAsync ( resolvedQuestion, submission ); if (userQuestionData.Submissions == null) { userQuestionData.Submissions = new List <UserQuestionSubmission>(); } var submissionContents = _jsonSerializer.Serialize(submission); var savedSubmission = new UserQuestionSubmission() { Score = scoredQuestionResult.Score, DateSubmitted = submissionDate, Seed = userQuestionData.Seed, CachedQuestionData = userQuestionData.CachedQuestionData, SubmissionContents = submissionContents }; userQuestionData.Submissions.Add(savedSubmission); userQuestionData.NumAttempts++; userQuestionData.Seed = null; if (userQuestionData.AssignmentQuestion.IsInteractive()) { userQuestionData.LastQuestionSubmission = submissionContents; } return(scoredQuestionResult); }
public void GetSubmissionScore_VerifyResult( string dateSubmitted, string dateDue, double score, bool withLateness, double expectedResult) { var submission = new UserQuestionSubmission() { DateSubmitted = DateTime.Parse(dateSubmitted), Score = score, UserQuestionData = new UserQuestionData() { AssignmentQuestion = new AssignmentQuestion() { Assignment = new Assignment() { Classroom = new Classroom() { DailyLatenessDeduction = 0.05, MaxLatenessDeduction = 0.2 } } } } }; var questionScoreCalculator = new QuestionScoreCalculator(); var result = questionScoreCalculator.GetSubmissionScore ( submission, dateDue != null ? (DateTime?)DateTime.Parse(dateDue) : null, 1.0 /*questionPoints*/, withLateness ); Assert.Equal(expectedResult, result); }
/// <summary> /// Returns a mock QuestionScoreCalculator. /// </summary> private IQuestionScoreCalculator GetMockQuestionScoreCalculator( UserQuestionSubmission submission, DateTime dueDate, double questionPoints, double scoreWithoutLateness, double scoreWithLateness) { var questionScoreCalculator = new Mock <IQuestionScoreCalculator>(); questionScoreCalculator .Setup ( m => m.GetSubmissionScore ( submission, dueDate, questionPoints, false /*withLateness*/ ) ).Returns(scoreWithoutLateness); questionScoreCalculator .Setup ( m => m.GetSubmissionScore ( submission, dueDate, questionPoints, true /*withLateness*/ ) ).Returns(scoreWithLateness); return(questionScoreCalculator.Object); }
/// <summary> /// Returns the actual question that was solved on a given submission. /// </summary> public async Task <Question> ResolveSolvedQuestionAsync( UserQuestionSubmission submission) { return(await ResolveQuestionAsync(submission.CachedQuestionData)); }
/// <summary> /// Returns the actual question that was solved on a given submission. /// </summary> public async Task <Question> ResolveSolvedQuestionAsync(UserQuestionSubmission submission) { return(await _prevSubmissionResolver.ResolveSolvedQuestionAsync(submission)); }
/// <summary> /// Returns the actual question that was solved on a given submission. /// </summary> public async Task <Question> ResolveSolvedQuestionAsync( UserQuestionSubmission submission) { return(await ResolveQuestionAsync(submission.Seed.Value)); }
/// <summary> /// Adds a question submission to the database. /// </summary> public TestDatabaseBuilder AddQuestionSubmission( string classroomName, string questionCategoryName, string questionName, string userName, string assignmentName, string submissionContents, double score = 0.0, DateTime?dateSubmitted = null, int?seed = null, string cachedQuestionData = null) { var assignmentQuestion = _buildContext.AssignmentQuestions .Where(aq => aq.Assignment.Name == assignmentName) .Where(aq => aq.Question.QuestionCategory.Classroom.Name == classroomName) .Where(aq => aq.Question.QuestionCategory.Name == questionCategoryName) .Single(aq => aq.Question.Name == questionName); var user = _buildContext.Users .Single(u => u.UserName == userName); var userQuestionData = _buildContext.UserQuestionData .Where(uqd => uqd.User == user) .SingleOrDefault(uqd => uqd.AssignmentQuestion == assignmentQuestion); if (userQuestionData == null) { userQuestionData = new UserQuestionData() { UserId = user.Id, AssignmentQuestionId = assignmentQuestion.Id, LastQuestionSubmission = submissionContents, CachedQuestionData = cachedQuestionData, CachedQuestionDataTime = dateSubmitted, Seed = seed }; _buildContext.UserQuestionData.Add(userQuestionData); } else { userQuestionData.LastQuestionSubmission = submissionContents; userQuestionData.CachedQuestionData = cachedQuestionData; userQuestionData.CachedQuestionDataTime = dateSubmitted; userQuestionData.Seed = seed; _buildContext.UserQuestionData.Update(userQuestionData); } var userQuestionSubmission = new UserQuestionSubmission() { DateSubmitted = dateSubmitted ?? DateTime.MinValue, UserQuestionData = userQuestionData, Score = score }; _buildContext.UserQuestionSubmissions.Add(userQuestionSubmission); _buildContext.SaveChanges(); return(this); }
public async Task GetSubmissionResultAsync_SubmissionFound_ReturnsCorrectResult() { var user = new User(); var userQuestionSubmission = new UserQuestionSubmission() { DateSubmitted = SubmissionDate, SubmissionContents = "Contents" }; var store = GetUserQuestionDataStore ( assignmentQuestionId: 1, assignmentQuestionName: "Question 1", user: user, numAttempts: 1, numAttemptsRemaining: 1, generated: true, seed: 12345, questionPoints: 1.0, pastSubmissions: Collections.CreateList ( userQuestionSubmission ) ); var status = CreateUserQuestionStatus(); var statusCalculator = GetMockQuestionStatusCalculator(store, status); var submission = CreateQuestionSubmission(assignmentQuestionId: 1); var serializer = GetMockJsonSerializer("Contents", submission); var resolvedQuestion = new MultipleChoiceQuestion(); var resolverFactory = GetMockQuestionResolverFactory ( store, resolvedQuestion, submission: userQuestionSubmission ); var questionResult = new MultipleChoiceQuestionResult(correct: true); var graderFactory = GetMockQuestionGraderFactory ( resolvedQuestion, submission, new ScoredQuestionResult(questionResult, score: 0.5) ); var scoreCalculator = GetMockQuestionScoreCalculator ( userQuestionSubmission, DueDate, questionPoints: 1.0, scoreWithoutLateness: 1.0, scoreWithLateness: 0.9 ); var questionSolver = GetQuestionSolver ( questionResolverFactory: resolverFactory, questionGraderFactory: graderFactory, questionStatusCalculator: statusCalculator, questionScoreCalculator: scoreCalculator, jsonSerializer: serializer ); var result = await questionSolver.GetSubmissionResultAsync ( store, assignmentQuestionId : 1, submissionDate : SubmissionDate, dueDate : DueDate ); Assert.Equal(1, result.QuestionSubmitted.AssignmentQuestionId); Assert.Equal("Question 1", result.QuestionSubmitted.Name); Assert.Equal(resolvedQuestion, result.QuestionSubmitted.Question); Assert.Equal(12345, result.QuestionSubmitted.Seed); Assert.Equal(user, result.QuestionSubmitted.User); Assert.Equal(submission, result.QuestionSubmitted.LastSubmission); Assert.False(result.QuestionSubmitted.Interactive); Assert.Equal(status, result.QuestionSubmitted.Status); Assert.Equal(1, result.QuestionSubmitted.PastSubmissions.Count); Assert.Equal(SubmissionDate, result.QuestionSubmitted.PastSubmissions[0]); Assert.Null(result.QuestionSubmitted.AssignmentProgress); Assert.Equal(questionResult, result.QuestionResult); Assert.Equal(1.0, result.QuestionPoints); Assert.Equal(SubmissionDate, result.SubmissionDate); Assert.Equal(1.0, result.ScoreWithoutLateness); Assert.Equal(0.9, result.ScoreWithLateness); }