We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add "public view" on results pages for staff users
For staff users there should be an option on the results pages to switch between "public view" (without comments, like students would see the page) and "complete view" (the current view including all comments).


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `evap/results/views.py`
Content:
```
1 from django.http import HttpResponse
2 from django.core.exceptions import PermissionDenied
3 from django.shortcuts import get_object_or_404, render
4 from django.utils.translation import get_language
5 from django.contrib.auth.decorators import login_required
6 
7 from evap.evaluation.auth import staff_required
8 from evap.evaluation.models import Semester, Degree
9 from evap.evaluation.tools import calculate_results, calculate_average_grades_and_deviation, TextResult
10 
11 from evap.results.exporters import ExcelExporter
12 
13 from collections import OrderedDict, namedtuple
14 
15 
16 @login_required
17 def index(request):
18     semesters = Semester.get_all_with_published_courses()
19 
20     return render(request, "results_index.html", dict(semesters=semesters))
21 
22 
23 @login_required
24 def semester_detail(request, semester_id):
25     semester = get_object_or_404(Semester, id=semester_id)
26     courses = list(semester.course_set.filter(state="published").prefetch_related("degrees"))
27 
28     # annotate each course object with its grades
29     for course in courses:
30         course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)
31 
32     CourseTuple = namedtuple('CourseTuple', ('courses', 'single_results'))
33 
34     courses_by_degree = OrderedDict()
35     for degree in Degree.objects.all():
36         courses_by_degree[degree] = CourseTuple([], [])
37     for course in courses:
38         if course.is_single_result():
39             for degree in course.degrees.all():
40                 section = calculate_results(course)[0]
41                 result = section.results[0]
42                 courses_by_degree[degree].single_results.append((course, result))
43         else:
44             for degree in course.degrees.all():
45                 courses_by_degree[degree].courses.append(course)
46 
47     template_data = dict(semester=semester, courses_by_degree=courses_by_degree, staff=request.user.is_staff)
48     return render(request, "results_semester_detail.html", template_data)
49 
50 
51 @staff_required
52 def semester_export(request, semester_id):
53     semester = get_object_or_404(Semester, id=semester_id)
54 
55     filename = "Evaluation-%s-%s.xls" % (semester.name, get_language())
56 
57     response = HttpResponse(content_type="application/vnd.ms-excel")
58     response["Content-Disposition"] = "attachment; filename=\"%s\"" % filename
59 
60     ExcelExporter(semester).export(response, 'all' in request.GET)
61 
62     return response
63 
64 
65 @login_required
66 def course_detail(request, semester_id, course_id):
67     semester = get_object_or_404(Semester, id=semester_id)
68     course = get_object_or_404(semester.course_set, id=course_id)
69 
70     if not course.can_user_see_results(request.user):
71         raise PermissionDenied
72 
73     sections = calculate_results(course)
74 
75     for section in sections:
76         results = []
77         for result in section.results:
78             if isinstance(result, TextResult):
79                 answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer)]
80                 if answers:
81                     results.append(TextResult(question=result.question, answers=answers))
82             else:
83                 results.append(result)
84         section.results[:] = results
85 
86     # filter empty sections and group by contributor
87     course_sections = []
88     contributor_sections = OrderedDict()
89     for section in sections:
90         if not section.results:
91             continue
92         if section.contributor is None:
93             course_sections.append(section)
94         else:
95             contributor_sections.setdefault(section.contributor, []).append(section)
96 
97     # show a warning if course is still in evaluation (for staff preview)
98     evaluation_warning = course.state != 'published'
99 
100     # results for a course might not be visible because there are not enough answers
101     # but it can still be "published" e.g. to show the comment results to contributors.
102     # users who can open the results page see a warning message in this case
103     sufficient_votes_warning = not course.can_publish_grades
104 
105     show_grades = request.user.is_staff or course.can_publish_grades
106 
107     course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)
108 
109     template_data = dict(
110             course=course,
111             course_sections=course_sections,
112             contributor_sections=contributor_sections,
113             evaluation_warning=evaluation_warning,
114             sufficient_votes_warning=sufficient_votes_warning,
115             show_grades=show_grades,
116             staff=request.user.is_staff)
117     return render(request, "results_course_detail.html", template_data)
118 
119 def user_can_see_text_answer(user, text_answer):
120     if user.is_staff:
121         return True
122     contributor = text_answer.contribution.contributor
123     if text_answer.is_private:
124         return contributor == user
125     if text_answer.is_published:
126         if contributor == user or contributor in user.represented_users.all():
127             return True
128         if text_answer.contribution.course.is_user_responsible_or_delegate(user):
129             return True
130 
131     return False
132
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/evap/results/views.py b/evap/results/views.py
--- a/evap/results/views.py
+++ b/evap/results/views.py
@@ -72,11 +72,14 @@
 
     sections = calculate_results(course)
 
+    public_view = request.GET.get('public_view', 'false') # default: show own view
+    public_view = {'true': True, 'false': False}.get(public_view.lower()) # convert parameter to boolean
+
     for section in sections:
         results = []
         for result in section.results:
             if isinstance(result, TextResult):
-                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer)]
+                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer, public_view)]
                 if answers:
                     results.append(TextResult(question=result.question, answers=answers))
             else:
@@ -113,10 +116,14 @@
             evaluation_warning=evaluation_warning,
             sufficient_votes_warning=sufficient_votes_warning,
             show_grades=show_grades,
-            staff=request.user.is_staff)
+            staff=request.user.is_staff,
+            contributor=course.is_user_contributor_or_delegate(request.user),
+            public_view=public_view)
     return render(request, "results_course_detail.html", template_data)
 
-def user_can_see_text_answer(user, text_answer):
+def user_can_see_text_answer(user, text_answer, public_view=False):
+    if public_view:
+        return False
     if user.is_staff:
         return True
     contributor = text_answer.contribution.contributor

{"golden_diff": "diff --git a/evap/results/views.py b/evap/results/views.py\n--- a/evap/results/views.py\n+++ b/evap/results/views.py\n@@ -72,11 +72,14 @@\n \n     sections = calculate_results(course)\n \n+    public_view = request.GET.get('public_view', 'false') # default: show own view\n+    public_view = {'true': True, 'false': False}.get(public_view.lower()) # convert parameter to boolean\n+\n     for section in sections:\n         results = []\n         for result in section.results:\n             if isinstance(result, TextResult):\n-                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer)]\n+                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer, public_view)]\n                 if answers:\n                     results.append(TextResult(question=result.question, answers=answers))\n             else:\n@@ -113,10 +116,14 @@\n             evaluation_warning=evaluation_warning,\n             sufficient_votes_warning=sufficient_votes_warning,\n             show_grades=show_grades,\n-            staff=request.user.is_staff)\n+            staff=request.user.is_staff,\n+            contributor=course.is_user_contributor_or_delegate(request.user),\n+            public_view=public_view)\n     return render(request, \"results_course_detail.html\", template_data)\n \n-def user_can_see_text_answer(user, text_answer):\n+def user_can_see_text_answer(user, text_answer, public_view=False):\n+    if public_view:\n+        return False\n     if user.is_staff:\n         return True\n     contributor = text_answer.contribution.contributor\n", "issue": "Add \"public view\" on results pages for staff users\nFor staff users there should be an option on the results pages to switch between \"public view\" (without comments, like students would see the page) and \"complete view\" (the current view including all comments).\n\n", "before_files": [{"content": "from django.http import HttpResponse\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, render\nfrom django.utils.translation import get_language\nfrom django.contrib.auth.decorators import login_required\n\nfrom evap.evaluation.auth import staff_required\nfrom evap.evaluation.models import Semester, Degree\nfrom evap.evaluation.tools import calculate_results, calculate_average_grades_and_deviation, TextResult\n\nfrom evap.results.exporters import ExcelExporter\n\nfrom collections import OrderedDict, namedtuple\n\n\n@login_required\ndef index(request):\n    semesters = Semester.get_all_with_published_courses()\n\n    return render(request, \"results_index.html\", dict(semesters=semesters))\n\n\n@login_required\ndef semester_detail(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    courses = list(semester.course_set.filter(state=\"published\").prefetch_related(\"degrees\"))\n\n    # annotate each course object with its grades\n    for course in courses:\n        course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)\n\n    CourseTuple = namedtuple('CourseTuple', ('courses', 'single_results'))\n\n    courses_by_degree = OrderedDict()\n    for degree in Degree.objects.all():\n        courses_by_degree[degree] = CourseTuple([], [])\n    for course in courses:\n        if course.is_single_result():\n            for degree in course.degrees.all():\n                section = calculate_results(course)[0]\n                result = section.results[0]\n                courses_by_degree[degree].single_results.append((course, result))\n        else:\n            for degree in course.degrees.all():\n                courses_by_degree[degree].courses.append(course)\n\n    template_data = dict(semester=semester, courses_by_degree=courses_by_degree, staff=request.user.is_staff)\n    return render(request, \"results_semester_detail.html\", template_data)\n\n\n@staff_required\ndef semester_export(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n\n    filename = \"Evaluation-%s-%s.xls\" % (semester.name, get_language())\n\n    response = HttpResponse(content_type=\"application/vnd.ms-excel\")\n    response[\"Content-Disposition\"] = \"attachment; filename=\\\"%s\\\"\" % filename\n\n    ExcelExporter(semester).export(response, 'all' in request.GET)\n\n    return response\n\n\n@login_required\ndef course_detail(request, semester_id, course_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    course = get_object_or_404(semester.course_set, id=course_id)\n\n    if not course.can_user_see_results(request.user):\n        raise PermissionDenied\n\n    sections = calculate_results(course)\n\n    for section in sections:\n        results = []\n        for result in section.results:\n            if isinstance(result, TextResult):\n                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer)]\n                if answers:\n                    results.append(TextResult(question=result.question, answers=answers))\n            else:\n                results.append(result)\n        section.results[:] = results\n\n    # filter empty sections and group by contributor\n    course_sections = []\n    contributor_sections = OrderedDict()\n    for section in sections:\n        if not section.results:\n            continue\n        if section.contributor is None:\n            course_sections.append(section)\n        else:\n            contributor_sections.setdefault(section.contributor, []).append(section)\n\n    # show a warning if course is still in evaluation (for staff preview)\n    evaluation_warning = course.state != 'published'\n\n    # results for a course might not be visible because there are not enough answers\n    # but it can still be \"published\" e.g. to show the comment results to contributors.\n    # users who can open the results page see a warning message in this case\n    sufficient_votes_warning = not course.can_publish_grades\n\n    show_grades = request.user.is_staff or course.can_publish_grades\n\n    course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)\n\n    template_data = dict(\n            course=course,\n            course_sections=course_sections,\n            contributor_sections=contributor_sections,\n            evaluation_warning=evaluation_warning,\n            sufficient_votes_warning=sufficient_votes_warning,\n            show_grades=show_grades,\n            staff=request.user.is_staff)\n    return render(request, \"results_course_detail.html\", template_data)\n\ndef user_can_see_text_answer(user, text_answer):\n    if user.is_staff:\n        return True\n    contributor = text_answer.contribution.contributor\n    if text_answer.is_private:\n        return contributor == user\n    if text_answer.is_published:\n        if contributor == user or contributor in user.represented_users.all():\n            return True\n        if text_answer.contribution.course.is_user_responsible_or_delegate(user):\n            return True\n\n    return False\n", "path": "evap/results/views.py"}], "after_files": [{"content": "from django.http import HttpResponse\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, render\nfrom django.utils.translation import get_language\nfrom django.contrib.auth.decorators import login_required\n\nfrom evap.evaluation.auth import staff_required\nfrom evap.evaluation.models import Semester, Degree\nfrom evap.evaluation.tools import calculate_results, calculate_average_grades_and_deviation, TextResult\n\nfrom evap.results.exporters import ExcelExporter\n\nfrom collections import OrderedDict, namedtuple\n\n\n@login_required\ndef index(request):\n    semesters = Semester.get_all_with_published_courses()\n\n    return render(request, \"results_index.html\", dict(semesters=semesters))\n\n\n@login_required\ndef semester_detail(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    courses = list(semester.course_set.filter(state=\"published\").prefetch_related(\"degrees\"))\n\n    # annotate each course object with its grades\n    for course in courses:\n        course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)\n\n    CourseTuple = namedtuple('CourseTuple', ('courses', 'single_results'))\n\n    courses_by_degree = OrderedDict()\n    for degree in Degree.objects.all():\n        courses_by_degree[degree] = CourseTuple([], [])\n    for course in courses:\n        if course.is_single_result():\n            for degree in course.degrees.all():\n                section = calculate_results(course)[0]\n                result = section.results[0]\n                courses_by_degree[degree].single_results.append((course, result))\n        else:\n            for degree in course.degrees.all():\n                courses_by_degree[degree].courses.append(course)\n\n    template_data = dict(semester=semester, courses_by_degree=courses_by_degree, staff=request.user.is_staff)\n    return render(request, \"results_semester_detail.html\", template_data)\n\n\n@staff_required\ndef semester_export(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n\n    filename = \"Evaluation-%s-%s.xls\" % (semester.name, get_language())\n\n    response = HttpResponse(content_type=\"application/vnd.ms-excel\")\n    response[\"Content-Disposition\"] = \"attachment; filename=\\\"%s\\\"\" % filename\n\n    ExcelExporter(semester).export(response, 'all' in request.GET)\n\n    return response\n\n\n@login_required\ndef course_detail(request, semester_id, course_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    course = get_object_or_404(semester.course_set, id=course_id)\n\n    if not course.can_user_see_results(request.user):\n        raise PermissionDenied\n\n    sections = calculate_results(course)\n\n    public_view = request.GET.get('public_view', 'false') # default: show own view\n    public_view = {'true': True, 'false': False}.get(public_view.lower()) # convert parameter to boolean\n\n    for section in sections:\n        results = []\n        for result in section.results:\n            if isinstance(result, TextResult):\n                answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, answer, public_view)]\n                if answers:\n                    results.append(TextResult(question=result.question, answers=answers))\n            else:\n                results.append(result)\n        section.results[:] = results\n\n    # filter empty sections and group by contributor\n    course_sections = []\n    contributor_sections = OrderedDict()\n    for section in sections:\n        if not section.results:\n            continue\n        if section.contributor is None:\n            course_sections.append(section)\n        else:\n            contributor_sections.setdefault(section.contributor, []).append(section)\n\n    # show a warning if course is still in evaluation (for staff preview)\n    evaluation_warning = course.state != 'published'\n\n    # results for a course might not be visible because there are not enough answers\n    # but it can still be \"published\" e.g. to show the comment results to contributors.\n    # users who can open the results page see a warning message in this case\n    sufficient_votes_warning = not course.can_publish_grades\n\n    show_grades = request.user.is_staff or course.can_publish_grades\n\n    course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)\n\n    template_data = dict(\n            course=course,\n            course_sections=course_sections,\n            contributor_sections=contributor_sections,\n            evaluation_warning=evaluation_warning,\n            sufficient_votes_warning=sufficient_votes_warning,\n            show_grades=show_grades,\n            staff=request.user.is_staff,\n            contributor=course.is_user_contributor_or_delegate(request.user),\n            public_view=public_view)\n    return render(request, \"results_course_detail.html\", template_data)\n\ndef user_can_see_text_answer(user, text_answer, public_view=False):\n    if public_view:\n        return False\n    if user.is_staff:\n        return True\n    contributor = text_answer.contribution.contributor\n    if text_answer.is_private:\n        return contributor == user\n    if text_answer.is_published:\n        if contributor == user or contributor in user.represented_users.all():\n            return True\n        if text_answer.contribution.course.is_user_responsible_or_delegate(user):\n            return True\n\n    return False\n", "path": "evap/results/views.py"}]}