def _save_skipped_answer(old_skipped, user_answer, paper, question): """ Saves the answer on skip. Only the code questions are saved. Snippet is not saved with the answer. """ if old_skipped: skipped_answer = old_skipped[0] skipped_answer.answer = user_answer skipped_answer.save() else: skipped_answer = Answer(question=question, answer=user_answer, correct=False, skipped=True) skipped_answer.save() paper.answers.add(skipped_answer)
def check(request, q_id, attempt_num=None, questionpaper_id=None): """Checks the answers of the user for particular question""" user = request.user q_paper = QuestionPaper.objects.get(id=questionpaper_id) paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_num, question_paper=q_paper) if q_id in paper.questions_answered: next_q = paper.skip(q_id) return show_question(request, next_q, attempt_num, questionpaper_id) if not user.is_authenticated() or paper.end_time < datetime.datetime.now(): return redirect("/home/") question = get_object_or_404(Question, pk=q_id) test_cases = TestCase.objects.filter(question=question) snippet_code = request.POST.get("snippet") user_code = request.POST.get("answer") skip = request.POST.get("skip", None) success_msg = False success = True if skip is not None: if question.type == "code": old_skipped = paper.answers.filter(question=question, skipped=True) _save_skipped_answer(old_skipped, user_code, paper, question) next_q = paper.skip(q_id) return show_question(request, next_q, attempt_num, questionpaper_id) # Add the answer submitted, regardless of it being correct or not. if question.type == "mcq": user_answer = request.POST.get("answer") elif question.type == "mcc": user_answer = request.POST.getlist("answer") new_answer = Answer(question=question, answer=user_answer, correct=False) new_answer.save() paper.answers.add(new_answer) # If we were not skipped, we were asked to check. For any non-mcq # questions, we obtain the results via XML-RPC with the code executed # safely in a separate process (the code_server.py) running as nobody. if not question.type == "upload": json_data = question.consolidate_answer_data(test_cases, user_answer) if question.type == "code" else None correct, result = validate_answer(user, user_answer, question, json_data) if correct: new_answer.correct = correct new_answer.marks = question.points new_answer.error = result.get("error") success_msg = True else: new_answer.error = result.get("error") new_answer.save() time_left = paper.time_left() if not result.get("success"): # Should only happen for non-mcq questions. if time_left == 0: reason = "Your time is up!" return complete(request, reason, attempt_num, questionpaper_id) if not paper.question_paper.quiz.active: reason = "The quiz has been deactivated!" return complete(request, reason, attempt_num, questionpaper_id) if not paper.question_paper.quiz.active: reason = "The quiz has been deactivated!" return complete(request, reason, attempt_num, questionpaper_id) questions, to_attempt, submitted = get_questions(paper) old_answer = paper.answers.filter(question=question, skipped=True) if old_answer: old_answer[0].answer = user_code old_answer[0].save() context = { "question": question, "error_message": result.get("error"), "paper": paper, "last_attempt": user_code, "quiz_name": paper.question_paper.quiz.description, "time_left": time_left, "questions": questions, "to_attempt": to_attempt, "submitted": submitted, } ci = RequestContext(request) return my_render_to_response("yaksh/question.html", context, context_instance=ci) else: if time_left <= 0: reason = "Your time is up!" return complete(request, reason, attempt_num, questionpaper_id) # Display the same question if user_answer is None elif not user_answer: msg = "Please submit a valid option or code" time_left = paper.time_left() questions, to_attempt, submitted = get_questions(paper) context = { "question": question, "error_message": msg, "paper": paper, "quiz_name": paper.question_paper.quiz.description, "time_left": time_left, "questions": questions, "to_attempt": to_attempt, "submitted": submitted, } ci = RequestContext(request) return my_render_to_response("yaksh/question.html", context, context_instance=ci) else: next_q = paper.completed_question(question.id) return show_question(request, next_q, attempt_num, questionpaper_id, success_msg)