From 9b16596d0c881ba932147359a2814861465d252c Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 9 Oct 2023 12:44:11 +0100 Subject: [PATCH] update sba testing (and fix others) --- generic/views.py | 60 +++++-- longs/tests/test_longs_exams.py | 10 +- physics/models.py | 10 ++ physics/urls.py | 20 +-- physics/views.py | 124 +++++++-------- rad/test_helpers.py | 182 +++++++++++++++------- rapids/models.py | 28 ++-- rapids/tests/test_rapids_exams.py | 5 + sbas/models.py | 2 +- sbas/templates/sbas/exam_scores_user.html | 4 +- sbas/tests/test_sbas_exams.py | 12 +- sbas/urls.py | 20 +-- sbas/views.py | 129 +++++++-------- 13 files changed, 363 insertions(+), 243 deletions(-) diff --git a/generic/views.py b/generic/views.py index 31108a84..46ac399b 100644 --- a/generic/views.py +++ b/generic/views.py @@ -1889,30 +1889,62 @@ class ExamViews(View, LoginRequiredMixin): print("ans", ans) print("ans score", answer_score) - correct_answer = q.get_primary_answer() + match self.app_name: + case "sbas": + correct_answer = q.get_correct_answer() - if not exam.publish_results and not view_all_results: - correct_answer = "*****" - answer_score = 0 - answers.append(ans) - answers_marks.append(answer_score) - answers_and_marks.append((ans, answer_score, correct_answer)) + if not exam.publish_results and not view_all_results: + correct_answer = "*****" + answer_score = 0 + answers.append(ans) + answers_marks.append(answer_score) + + merged_ans = (ans, answer_score, correct_answer) + chosen_answer = q.get_answer_by_choice(ans) + answers_and_marks.append((q, *merged_ans, chosen_answer)) + case "physics": + correct_answer = q.get_answers() + + if not exam.publish_results and not view_all_results: + correct_answer = ("*****", "*****", "*****", "*****", "*****") + answer_score = (0, 0, 0, 0, 0) + answers.append(ans) + answers_marks.append(answer_score) + + print(q.get_questions(), ans, answer_score, correct_answer) + merged_ans = zip(q.get_questions(), ans, answer_score, correct_answer) + answers_and_marks.append((q, merged_ans)) + case _: + correct_answer = q.get_primary_answer() + + if not exam.publish_results and not view_all_results: + correct_answer = "*****" + answer_score = 0 + answers.append(ans) + answers_marks.append(answer_score) + answers_and_marks.append((ans, answer_score, correct_answer)) print(answers_marks) - if "unmarked" in answers_marks: - answered = [i for i in answers_marks if type(i) == int] - total_score = sum(answered) - unmarked_number = len(answers_marks) - len(answered) - total_score = "{} ({} unmarked)".format(total_score, unmarked_number) - else: - total_score = sum(answers_marks) + match self.app_name: + case "physics": + total_score = sum(sum(i) for i in answers_marks) + case _: + if "unmarked" in answers_marks: + answered = [i for i in answers_marks if type(i) == int] + total_score = sum(answered) + unmarked_number = len(answers_marks) - len(answered) + total_score = "{} ({} unmarked)".format(total_score, unmarked_number) + else: + total_score = sum(answers_marks) match self.app_name: case "rapids" | "anatomy": max_score = len(questions) * 2 case "longs": max_score = len(questions) * 8 + case "physics": + max_score = len(questions) * 5 case _: max_score = len(questions) diff --git a/longs/tests/test_longs_exams.py b/longs/tests/test_longs_exams.py index 0c58f420..ac36e0d3 100644 --- a/longs/tests/test_longs_exams.py +++ b/longs/tests/test_longs_exams.py @@ -74,19 +74,19 @@ def create_long_series(question, image_number=5): series.save() for n in range(image_number): - create_long_series_image(series) + create_long_series_image(series, n) return series -def create_long_series_image(series): +def create_long_series_image(series, n=0): image = tempfile.NamedTemporaryFile( - dir=settings.MEDIA_ROOT, suffix=".jpg", delete=False + dir=settings.MEDIA_ROOT, suffix="{n}.jpg", delete=False ) - long_series_image = LongSeriesImage.objects.create(image=image.name, series=series) + long_series_image = LongSeriesImage(image=image.name, series=series) - # long_series_image.save() + long_series_image.save() def create_question(exam, answer=None, normal=False): diff --git a/physics/models.py b/physics/models.py index df5cccaa..644c3e7f 100644 --- a/physics/models.py +++ b/physics/models.py @@ -128,6 +128,13 @@ class Question(QuestionBase): def get_questions(self): return [self.a, self.b, self.c, self.d, self.e] + def get_unanswered_mark_and_text(self) -> tuple[int, tuple[str, str, str, str, str]]: + """ + + returns score, tuple[answers] + """ + return ((0,) * 5, ("Not answered",) * 5) + #@reversion.register class Exam(ExamBase): @@ -209,6 +216,9 @@ class UserAnswer(UserAnswerBase): def get_answers(self): return (self.a, self.b, self.c, self.d, self.e) + def get_answer(self): + return self.get_answers() + def get_answer_string(self): return [str(i) for i in (self.a, self.b, self.c, self.d, self.e)] diff --git a/physics/urls.py b/physics/urls.py index 3a11e6ef..cf6c29c3 100644 --- a/physics/urls.py +++ b/physics/urls.py @@ -60,16 +60,16 @@ urlpatterns.extend( name="user_answer_delete", ), # TODO: consider merging with generic... - path( - "exam//scores///", - views.exam_scores_cid_user, - name="exam_scores_cid_user", - ), - path( - "exam//scores/", - views.exam_scores_cid_user, - name="exam_scores_user", - ), + #path( + # "exam//scores///", + # views.exam_scores_cid_user, + # name="exam_scores_cid_user", + #), + #path( + # "exam//scores/", + # views.exam_scores_cid_user, + # name="exam_scores_user", + #), ] ) diff --git a/physics/views.py b/physics/views.py index f21b1413..4e9e0994 100644 --- a/physics/views.py +++ b/physics/views.py @@ -100,68 +100,68 @@ def active_exams(request): return render(request, "physics/available_exam_list.html", {"exams": active_exams}) -def exam_scores_cid_user(request, pk, cid=None, passcode=None): - exam = get_object_or_404(Exam, pk=pk) - - exam.check_user_can_review(cid, passcode, request) - - questions = exam.exam_questions.all() - - answers_and_marks = [] - answers_marks = [] - answers = [] - - view_all_results = False - if request.user.groups.filter(name="view_all_results").exists(): - view_all_results = True - - for q in questions: - # Get user answer - if cid is not None: - user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first() - else: - user_answer = q.cid_user_answers.filter( - user=request.user, exam__id=pk - ).first() - - if user_answer is None: - answer_scores = (0, 0, 0, 0, 0) - ans = ("", "", "", "", "") - else: - ans = user_answer.get_answers() - answer_scores = user_answer.get_answer_score() - - correct_answers = q.get_answers() - - if not exam.publish_results and not view_all_results: - correct_answers = ("*****", "*****", "*****", "*****", "*****") - answer_scores = (0, 0, 0, 0, 0) - answers.append(ans) - answers_marks.append(answer_scores) - - merged_ans = zip(q.get_questions(), ans, answer_scores, correct_answers) - answers_and_marks.append((q, merged_ans)) - - total_score = sum(sum(i) for i in answers_marks) - - max_score = len(questions) * 5 - - return render( - request, - "physics/exam_scores_user.html", - { - "exam": exam, - "cid": cid, - "passcode": passcode, - "questions": questions, - "answers": answers, - "answers_marks": answers_marks, - "total_score": total_score, - "max_score": max_score, - "answers_and_marks": answers_and_marks, - "view_all_results": view_all_results, - }, - ) +#def exam_scores_cid_user(request, pk, cid=None, passcode=None): +# exam = get_object_or_404(Exam, pk=pk) +# +# exam.check_user_can_review(cid, passcode, request) +# +# questions = exam.exam_questions.all() +# +# answers_and_marks = [] +# answers_marks = [] +# answers = [] +# +# view_all_results = False +# if request.user.groups.filter(name="view_all_results").exists(): +# view_all_results = True +# +# for q in questions: +# # Get user answer +# if cid is not None: +# user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first() +# else: +# user_answer = q.cid_user_answers.filter( +# user=request.user, exam__id=pk +# ).first() +# +# if user_answer is None: +# answer_scores = (0, 0, 0, 0, 0) +# ans = ("", "", "", "", "") +# else: +# ans = user_answer.get_answers() +# answer_scores = user_answer.get_answer_score() +# +# correct_answers = q.get_answers() +# +# if not exam.publish_results and not view_all_results: +# correct_answers = ("*****", "*****", "*****", "*****", "*****") +# answer_scores = (0, 0, 0, 0, 0) +# answers.append(ans) +# answers_marks.append(answer_scores) +# +# merged_ans = zip(q.get_questions(), ans, answer_scores, correct_answers) +# answers_and_marks.append((q, merged_ans)) +# +# total_score = sum(sum(i) for i in answers_marks) +# +# max_score = len(questions) * 5 +# +# return render( +# request, +# "physics/exam_scores_user.html", +# { +# "exam": exam, +# "cid": cid, +# "passcode": passcode, +# "questions": questions, +# "answers": answers, +# "answers_marks": answers_marks, +# "total_score": total_score, +# "max_score": max_score, +# "answers_and_marks": answers_and_marks, +# "view_all_results": view_all_results, +# }, +# ) def exam_take_old(request, pk): diff --git a/rad/test_helpers.py b/rad/test_helpers.py index 6983e477..bc708918 100644 --- a/rad/test_helpers.py +++ b/rad/test_helpers.py @@ -11,6 +11,7 @@ from django.contrib.auth.models import User from django.urls import reverse from rich.pretty import pprint + def AssertNotFound(client, url): """Helper to quickly test for urls that should return a 404 (NOT FOUND) error""" response = client.get(url) @@ -74,9 +75,11 @@ class ExamTester: cidgroup1: CidUserGroup = CidUserGroup.objects.get(name="Group1") + self.answers_per_question = 1 match app_name: case "physics": assert exam in cidgroup1.physics_cid_user_groups.all() + self.answers_per_question = 5 case "sbas": assert exam in cidgroup1.sba_cid_user_groups.all() @@ -123,7 +126,9 @@ class ExamTester: def check_active_exams(self, n): active_exams = self.client.get(reverse(f"{self.app_name}:active_exams")) assert active_exams.status_code == 200 - assert len(json.loads(active_exams.content)["exams"]) == n, f"Current user: {self.current_user}" + assert ( + len(json.loads(active_exams.content)["exams"]) == n + ), f"Current user: {self.current_user}" def check_onsite_start_page(self): start_page_res = self.client.get( @@ -169,7 +174,9 @@ class ExamTester: assert cid_take_res.status_code == HTTPStatus.NOT_FOUND continue else: - assert cid_take_res.status_code == HTTPStatus.OK, f"Current user: {self.current_user}" + assert ( + cid_take_res.status_code == HTTPStatus.OK + ), f"Current user: {self.current_user}" cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser") @@ -207,14 +214,39 @@ class ExamTester: match self.app_name: case "physics": - assert cid_take_soup.find("label", {"for": "id_a"}).string == question.a - assert cid_take_soup.find("label", {"for": "id_b"}).string == question.b - assert cid_take_soup.find("label", {"for": "id_c"}).string == question.c - assert cid_take_soup.find("label", {"for": "id_d"}).string == question.d - assert cid_take_soup.find("label", {"for": "id_e"}).string == question.e + assert ( + cid_take_soup.find("label", {"for": "id_a"}).string + == question.a + ) + assert ( + cid_take_soup.find("label", {"for": "id_b"}).string + == question.b + ) + assert ( + cid_take_soup.find("label", {"for": "id_c"}).string + == question.c + ) + assert ( + cid_take_soup.find("label", {"for": "id_d"}).string + == question.d + ) + assert ( + cid_take_soup.find("label", {"for": "id_e"}).string + == question.e + ) case "sbas": - assert cid_take_soup.find("ul", {"class": "sba-answer-list"}) is not None - assert len(cid_take_soup.find("ul", {"class": "sba-answer-list"}).find_all("li")) == 5 + assert ( + cid_take_soup.find("ul", {"class": "sba-answer-list"}) + is not None + ) + assert ( + len( + cid_take_soup.find( + "ul", {"class": "sba-answer-list"} + ).find_all("li") + ) + == 5 + ) # As we haven't submitted any answers they should all be blank assert ( @@ -396,18 +428,21 @@ class ExamTester: # Check that we are showing enough questions / answers match self.app_name: case "physics": - answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"}) + answer_lis = cid_exam_scores_soup.find_all( + "li", {"class": "question-part"} + ) assert len(answer_lis) == 5 * len(self.generated_questions) assert len(submitted_answers) == 5 * len(self.generated_questions) for ans in submitted_answers: assert ans.text.strip() == "True" case "sbas": - answer_lis = cid_exam_scores_soup.find_all("li", {"class": "user-answer-li"}) + answer_lis = cid_exam_scores_soup.find_all( + "li", {"class": "user-answer-li"} + ) assert len(answer_lis) == len(self.generated_questions) assert len(submitted_answers) == len(self.generated_questions) - for ans in submitted_answers: assert ans.text.strip() == "a" @@ -426,7 +461,9 @@ class ExamTester: ) match self.app_name: case "physics": - answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"}) + answer_lis = cid_exam_scores_soup.find_all( + "li", {"class": "question-part"} + ) assert len(answer_lis) == 5 * len(self.generated_questions) assert len(submitted_answers) == 5 * len(self.generated_questions) @@ -435,10 +472,12 @@ class ExamTester: # The new question will not have any answers for ans in submitted_answers[-5:]: - assert ans.text.strip() == "" + assert ans.text.strip() == "Not answered" case "sbas": - answer_lis = cid_exam_scores_soup.find_all("li", {"class": "user-answer-li"}) + answer_lis = cid_exam_scores_soup.find_all( + "li", {"class": "user-answer-li"} + ) assert len(answer_lis) == len(self.generated_questions) assert len(submitted_answers) == len(self.generated_questions) @@ -451,9 +490,7 @@ class ExamTester: # The new question will not have any answers for ans in submitted_answers[3:]: print("test2", ans) - assert ans.text.strip() == "" - - + assert ans.text.strip() == "Not answered" # Publish the results! self.exam.publish_results = True @@ -471,56 +508,92 @@ class ExamTester: correct_answers = cid_exam_scores_soup.find_all( "span", {"class": "correct-answer"} ) - assert len(correct_answers) == 5 * len(self.generated_questions) + + assert len(correct_answers) == self.answers_per_question * len( + self.generated_questions + ) n = 0 - for question in self.generated_questions: - for ans in question.get_answers(): - assert correct_answers[n].text.strip() == f"Correct answer: {ans}" - n = n + 1 + for i, question in enumerate(self.generated_questions): + match self.app_name: + case "physics": + for ans in question.get_answers(): + assert correct_answers[n].text.strip() == f"Correct answer: {ans}" + n = n + 1 + case "sbas": + ans = question.get_correct_answer() + assert correct_answers[i].text.strip() == f"Correct answer: {ans}" submitted_answers = cid_exam_scores_soup.find_all( "span", {"class": "submitted-user-answer"} ) - assert len(submitted_answers) == 5 * len(self.generated_questions) + assert len(submitted_answers) == self.answers_per_question * len( + self.generated_questions + ) - for ans in submitted_answers[:-5]: - assert ans.text.strip() == "True" + print(submitted_answers) + + for ans in submitted_answers[:-self.answers_per_question]: + print("------", ans.text.strip()) + match self.app_name: + case "physics": + assert ans.text.strip() == "True" + case "sbas": + assert ans.text.strip() == "a" # The new question will not have any answers - for ans in submitted_answers[-5:]: - assert ans.text.strip() == "" - - assert ( - cid_exam_scores_soup.find("div", {"class": "score-overview"}) - .find("span", {"id": "total-score"}) - .string - == "9" - ) - assert ( - cid_exam_scores_soup.find("div", {"class": "score-overview"}) - .find("span", {"id": "max-score"}) - .string - == "20" - ) - + for ans in submitted_answers[-self.answers_per_question:]: + assert ans.text.strip() == "Not answered" + match self.app_name: + case "physics": + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "total-score"}) + .string + == "9" + ) + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "max-score"}) + .string + == "20" + ) + case "sbas": + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "total-score"}) + .string + == "3" + ) + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "max-score"}) + .string + == "4" + ) def check_cid_scores_user_page2(self): - cid_exam_scores_res = self.client.get(self.exam_scores_url) cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") - - - # As we have answered correctly the new score should be increased by 5 - assert ( - cid_exam_scores_soup.find("div", {"class": "score-overview"}) - .find("span", {"id": "total-score"}) - .string - == "14" - ), f"Current user: {self.current_user}" + # As we have answered correctly the new score should be increased by 1 * answer_count + match self.app_name: + case "physics": + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "total-score"}) + .string + == "14" + ), f"Invalid answer count, Current user: {self.current_user}" + case "sbas": + assert ( + cid_exam_scores_soup.find("div", {"class": "score-overview"}) + .find("span", {"id": "total-score"}) + .string + == "4" + ), f"Invalid answer count, Current user: {self.current_user}" # Check what happens when exam is not active self.exam.active = False @@ -553,9 +626,10 @@ class ExamTester: ) cid_take_res = self.client.get(cid_take_url) cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser") + print(cid_take_soup.text) assert "Exam is currently inactive" in cid_take_soup.text # Delete the last question, from both the list - q= self.generated_questions.pop() + q = self.generated_questions.pop() # and the database - q.delete() \ No newline at end of file + q.delete() diff --git a/rapids/models.py b/rapids/models.py index eca724a0..bfac3b6b 100644 --- a/rapids/models.py +++ b/rapids/models.py @@ -31,8 +31,8 @@ from generic.models import ( ExamUserStatus, QuestionBase, Site, - #Condition, - #Sign, + # Condition, + # Sign, ExamBase, QuestionNote, UserAnswerBase, @@ -308,7 +308,7 @@ class Rapid(QuestionBase): exams = ", ".join(e) return exams - def get_unmarked_user_answer_string(self, exam_pk: int=None): + def get_unmarked_user_answer_string(self, exam_pk: int = None): unmarked_answers = self.get_unmarked_user_answers(exam_pk) if not unmarked_answers: @@ -319,7 +319,7 @@ class Rapid(QuestionBase): ) ) - def get_unmarked_user_answers(self, exam_pk: int|None=None, marker=None): + def get_unmarked_user_answers(self, exam_pk: int | None = None, marker=None): # If normal no answers to mark (they will be automarked) if self.normal: return [] @@ -470,20 +470,25 @@ class Rapid(QuestionBase): return new_answers def get_question_json( - self, based: bool = True, feedback: bool = False, answers: bool = True, history: bool = False, annotations: bool = False + self, + based: bool = True, + feedback: bool = False, + answers: bool = True, + history: bool = False, + annotations: bool = False, ) -> QuestionData: """Returns a json representation of the question""" # Loop through rapidimage associations images = [] - annotations = [] + annotations_list = [] feedback_images = [] for i in self.images.all(): # TODO: add anotations if i.feedback_image == True: if feedback: - annotations.append(i.image_annotations) + annotations_list.append(i.image_annotations) if based: feedback_images.append(image_as_base64(i.image)) else: @@ -492,7 +497,7 @@ class Rapid(QuestionBase): ) # feedback_images.append("{}/{}".format(settings.REMOTE_URL, i.image.url)) else: - annotations.append(i.image_annotations) + annotations_list.append(i.image_annotations) if based: images.append(image_as_base64(i.image)) else: @@ -504,8 +509,8 @@ class Rapid(QuestionBase): "type": "rapid", } - if annotations: - json["annotations"] = annotations + if annotations: + json["annotations"] = annotations_list if history: json["history"] = self.history @@ -736,6 +741,7 @@ class Exam(ExamBase): @reversion.register class UserAnswer(UserAnswerBase): """User answers by candidate""" + app_name = "rapids" question = models.ForeignKey( @@ -748,7 +754,6 @@ class UserAnswer(UserAnswerBase): answer_compare = models.TextField(max_length=500, blank=True) - user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, @@ -781,7 +786,6 @@ class UserAnswer(UserAnswerBase): ) def __str__(self): - name = self.get_candidate_name() try: diff --git a/rapids/tests/test_rapids_exams.py b/rapids/tests/test_rapids_exams.py index 06203a0c..616375dd 100644 --- a/rapids/tests/test_rapids_exams.py +++ b/rapids/tests/test_rapids_exams.py @@ -57,6 +57,8 @@ def create_rapid_image(question): image = tempfile.NamedTemporaryFile( dir=settings.MEDIA_ROOT, suffix=".jpg", delete=False ) + image.flush() + image._committed = True rapid_image = RapidImage(image=image, rapid=question) @@ -189,6 +191,9 @@ def test_exams(db, client): assert res.status_code == 200 exam_json = json.loads(res.content) print(exam_json) + print(exam_json["questions"].values()) + print("----") + print(question1.get_question_json(answers=False)) assert ( question1.get_question_json(answers=False) diff --git a/sbas/models.py b/sbas/models.py index 23a42d97..fa1e2eab 100644 --- a/sbas/models.py +++ b/sbas/models.py @@ -213,7 +213,7 @@ class UserAnswer(UserAnswerBase): answer = models.CharField( max_length=20, choices=Question.BEST_ANSWER_CHOICES, - help_text="The correct answer", + help_text="The user selected answer", ) user = models.ForeignKey( diff --git a/sbas/templates/sbas/exam_scores_user.html b/sbas/templates/sbas/exam_scores_user.html index 7840ec59..679a18c6 100644 --- a/sbas/templates/sbas/exam_scores_user.html +++ b/sbas/templates/sbas/exam_scores_user.html @@ -20,8 +20,8 @@ Correct answer: {{correct_answer|safe}}
{% endif %} - - Chosen answer: {{chosen_answer|safe}} + Chosen answer: + {{chosen_answer|safe}} {% if exam.publish_results or view_all_results %} (Score: {{score}}) {% endif %} diff --git a/sbas/tests/test_sbas_exams.py b/sbas/tests/test_sbas_exams.py index fe17a52b..8b69c876 100644 --- a/sbas/tests/test_sbas_exams.py +++ b/sbas/tests/test_sbas_exams.py @@ -190,22 +190,14 @@ def test_exams(db, client): if exam_tester.testing_cid_user: cid_user_answer = UserAnswer( question=extra_question, - a=True, - b=False, - c=True, - d=False, - e=True, + answer = "a", cid=cid_user.cid, exam=exam, ) else: cid_user_answer = UserAnswer( question=extra_question, - a=True, - b=False, - c=True, - d=False, - e=True, + answer = "a", user=exam_tester.current_user, exam=exam, ) diff --git a/sbas/urls.py b/sbas/urls.py index 5bf0d6f3..4917b88c 100644 --- a/sbas/urls.py +++ b/sbas/urls.py @@ -72,16 +72,16 @@ urlpatterns = [ views.UserAnswerDelete.as_view(), name="user_answer_delete", ), - path( - "exam//scores///", - views.exam_scores_cid_user, - name="exam_scores_cid_user", - ), - path( - "exam//scores/", - views.exam_scores_cid_user, - name="exam_scores_user", - ), + #path( + # "exam//scores///", + # views.exam_scores_cid_user, + # name="exam_scores_cid_user", + #), + #path( + # "exam//scores/", + # views.exam_scores_cid_user, + # name="exam_scores_user", + #), ] urlpatterns.extend(generic_view_urls(views.GenericViews)) diff --git a/sbas/views.py b/sbas/views.py index 39892eb6..e09086e7 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -99,69 +99,69 @@ def active_exams(request): return render(request, "sbas/available_exam_list.html", {"exams": active_exams}) -def exam_scores_cid_user(request, pk, cid=None, passcode=None): - exam = get_object_or_404(Exam, pk=pk) - - exam.check_user_can_review(cid, passcode, request) - - questions = exam.exam_questions.all() - - answers_and_marks = [] - answers_marks = [] - answers = [] - - view_all_results = False - if request.user.groups.filter(name="view_all_results").exists(): - view_all_results = True - - for q in questions: - # Get user answer - if cid is not None: - user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first() - else: - user_answer = q.cid_user_answers.filter( - user=request.user, exam__id=pk - ).first() - - if user_answer is None: - answer_score = 0 - ans = "" - else: - answer_score = user_answer.get_answer_score() - ans = user_answer.get_answer() - - correct_answer = q.get_correct_answer() - - if not exam.publish_results and not view_all_results: - correct_answer = "*****" - answer_score = 0 - answers.append(ans) - answers_marks.append(answer_score) - - merged_ans = (ans, answer_score, correct_answer) - chosen_answer = q.get_answer_by_choice(ans) - answers_and_marks.append((q, *merged_ans, chosen_answer)) - - total_score = sum(answers_marks) - - max_score = len(questions) - - return render( - request, - "sbas/exam_scores_user.html", - { - "exam": exam, - "cid": cid, - "passcode": passcode, - "questions": questions, - "answers": answers, - "answers_marks": answers_marks, - "total_score": total_score, - "max_score": max_score, - "answers_and_marks": answers_and_marks, - "view_all_results": view_all_results, - }, - ) +#def exam_scores_cid_user(request, pk, cid=None, passcode=None): +# exam = get_object_or_404(Exam, pk=pk) +# +# exam.check_user_can_review(cid, passcode, request) +# +# questions = exam.exam_questions.all() +# +# answers_and_marks = [] +# answers_marks = [] +# answers = [] +# +# view_all_results = False +# if request.user.groups.filter(name="view_all_results").exists(): +# view_all_results = True +# +# for q in questions: +# # Get user answer +# if cid is not None: +# user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first() +# else: +# user_answer = q.cid_user_answers.filter( +# user=request.user, exam__id=pk +# ).first() +# +# if user_answer is None: +# answer_score = 0 +# ans = "" +# else: +# answer_score = user_answer.get_answer_score() +# ans = user_answer.get_answer() +# +# correct_answer = q.get_correct_answer() +# +# if not exam.publish_results and not view_all_results: +# correct_answer = "*****" +# answer_score = 0 +# answers.append(ans) +# answers_marks.append(answer_score) +# +# merged_ans = (ans, answer_score, correct_answer) +# chosen_answer = q.get_answer_by_choice(ans) +# answers_and_marks.append((q, *merged_ans, chosen_answer)) +# +# total_score = sum(answers_marks) +# +# max_score = len(questions) +# +# return render( +# request, +# "sbas/exam_scores_user.html", +# { +# "exam": exam, +# "cid": cid, +# "passcode": passcode, +# "questions": questions, +# "answers": answers, +# "answers_marks": answers_marks, +# "total_score": total_score, +# "max_score": max_score, +# "answers_and_marks": answers_and_marks, +# "view_all_results": view_all_results, +# }, +# ) def exam_start(request, pk): @@ -225,6 +225,9 @@ def exam_take_overview(request, pk, cid=None, passcode=None): def exam_take(request, pk: int, sk: int, cid: int = None, passcode: str = None): exam = get_object_or_404(Exam, pk=pk) + if not exam.active: + return exam_inactive(request, context={"exam": exam}) + exam.check_user_can_take(cid, passcode, request) cid_user_exam = exam.get_or_create_cid_user_exam(cid = cid, user_user=request.user)