prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Staff users should see the public view of results by default
  Staff users should by default see the public view of results pages. It shows less data (primarily no comments), which is good, and random people looking over one's shoulder won't ask "omg you see more stuff here why is that"
  
  --- 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 collections import OrderedDict, namedtuple
  2 
  3 from django.core.exceptions import PermissionDenied
  4 from django.shortcuts import get_object_or_404, render
  5 from django.contrib.auth.decorators import login_required
  6 
  7 from evap.evaluation.models import Semester, Degree, Contribution
  8 from evap.results.tools import calculate_results, calculate_average_grades_and_deviation, TextResult, RatingResult, COMMENT_STATES_REQUIRED_FOR_VISIBILITY
  9 
  10 
  11 @login_required
  12 def index(request):
  13     semesters = Semester.get_all_with_published_courses()
  14 
  15     return render(request, "results_index.html", dict(semesters=semesters))
  16 
  17 
  18 @login_required
  19 def semester_detail(request, semester_id):
  20     semester = get_object_or_404(Semester, id=semester_id)
  21     if request.user.is_reviewer:
  22         courses = list(semester.course_set.filter(state__in=["in_evaluation", "evaluated", "reviewed", "published"]).prefetch_related("degrees"))
  23     else:
  24         courses = list(semester.course_set.filter(state="published").prefetch_related("degrees"))
  25 
  26     courses = [course for course in courses if course.can_user_see_course(request.user)]
  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)
  48     return render(request, "results_semester_detail.html", template_data)
  49 
  50 
  51 @login_required
  52 def course_detail(request, semester_id, course_id):
  53     semester = get_object_or_404(Semester, id=semester_id)
  54     course = get_object_or_404(semester.course_set, id=course_id, semester=semester)
  55 
  56     if not course.can_user_see_results(request.user):
  57         raise PermissionDenied
  58 
  59     sections = calculate_results(course)
  60 
  61     public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.
  62 
  63     represented_users = list(request.user.represented_users.all())
  64     represented_users.append(request.user)
  65 
  66     # filter text answers
  67     for section in sections:
  68         results = []
  69         for result in section.results:
  70             if isinstance(result, TextResult):
  71                 answers = [answer for answer in result.answers if user_can_see_text_answer(request.user, represented_users, answer, public_view)]
  72                 if answers:
  73                     results.append(TextResult(question=result.question, answers=answers))
  74             else:
  75                 results.append(result)
  76         section.results[:] = results
  77 
  78     # remove empty sections
  79     sections = [section for section in sections if section.results]
  80 
  81     # group by contributor
  82     course_sections = []
  83     contributor_sections = OrderedDict()
  84     for section in sections:
  85         if not section.results:
  86             continue
  87         if section.contributor is None:
  88             course_sections.append(section)
  89         else:
  90             contributor_sections.setdefault(section.contributor,
  91                                             {'total_votes': 0, 'sections': []})['sections'].append(section)
  92 
  93             # Sum up all Sections for this contributor.
  94             # If section is not a RatingResult:
  95             # Add 1 as we assume it is a TextResult or something similar that should be displayed.
  96             contributor_sections[section.contributor]['total_votes'] +=\
  97                 sum([s.total_count if isinstance(s, RatingResult) else 1 for s in section.results])
  98 
  99     # Show a warning if course is still in evaluation (for reviewer preview).
  100     evaluation_warning = course.state != 'published'
  101 
  102     # Results for a course might not be visible because there are not enough answers
  103     # but it can still be "published" e.g. to show the comment results to contributors.
  104     # Users who can open the results page see a warning message in this case.
  105     sufficient_votes_warning = not course.can_publish_grades
  106 
  107     show_grades = request.user.is_reviewer or course.can_publish_grades
  108 
  109     course.avg_grade, course.avg_deviation = calculate_average_grades_and_deviation(course)
  110 
  111     template_data = dict(
  112             course=course,
  113             course_sections=course_sections,
  114             contributor_sections=contributor_sections,
  115             evaluation_warning=evaluation_warning,
  116             sufficient_votes_warning=sufficient_votes_warning,
  117             show_grades=show_grades,
  118             reviewer=request.user.is_reviewer,
  119             contributor=course.is_user_contributor_or_delegate(request.user),
  120             can_download_grades=request.user.can_download_grades,
  121             public_view=public_view)
  122     return render(request, "results_course_detail.html", template_data)
  123 
  124 
  125 def user_can_see_text_answer(user, represented_users, text_answer, public_view=False):
  126     if public_view:
  127         return False
  128     if text_answer.state not in COMMENT_STATES_REQUIRED_FOR_VISIBILITY:
  129         return False
  130     if user.is_reviewer:
  131         return True
  132 
  133     contributor = text_answer.contribution.contributor
  134 
  135     if text_answer.is_private:
  136         return contributor == user
  137 
  138     if text_answer.is_published:
  139         if text_answer.contribution.responsible:
  140             return contributor == user or user in contributor.delegates.all()
  141 
  142         if contributor in represented_users:
  143             return True
  144         if text_answer.contribution.course.contributions.filter(
  145                 contributor__in=represented_users, comment_visibility=Contribution.ALL_COMMENTS).exists():
  146             return True
  147         if text_answer.contribution.is_general and text_answer.contribution.course.contributions.filter(
  148                 contributor__in=represented_users, comment_visibility=Contribution.COURSE_COMMENTS).exists():
  149             return True
  150 
  151     return False
  152
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/evap/results/views.py b/evap/results/views.py
  --- a/evap/results/views.py
  +++ b/evap/results/views.py
  @@ -58,7 +58,10 @@
   
       sections = calculate_results(course)
   
  -    public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.
  +    if request.user.is_staff or request.user.is_reviewer:
  +        public_view = request.GET.get('public_view') != 'false'  # if parameter is not given, show public view.
  +    else:
  +        public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.
   
       represented_users = list(request.user.represented_users.all())
       represented_users.append(request.user)
  
verification_info: {"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@@ -58,7 +58,10 @@\n \n     sections = calculate_results(course)\n \n-    public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.\n+    if request.user.is_staff or request.user.is_reviewer:\n+        public_view = request.GET.get('public_view') != 'false'  # if parameter is not given, show public view.\n+    else:\n+        public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.\n \n     represented_users = list(request.user.represented_users.all())\n     represented_users.append(request.user)\n", "issue": "Staff users should see the public view of results by default\nStaff users should by default see the public view of results pages. It shows less data (primarily no comments), which is good, and random people looking over one's shoulder won't ask \"omg you see more stuff here why is that\"\n", "before_files": [{"content": "from collections import OrderedDict, namedtuple\n\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, render\nfrom django.contrib.auth.decorators import login_required\n\nfrom evap.evaluation.models import Semester, Degree, Contribution\nfrom evap.results.tools import calculate_results, calculate_average_grades_and_deviation, TextResult, RatingResult, COMMENT_STATES_REQUIRED_FOR_VISIBILITY\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    if request.user.is_reviewer:\n        courses = list(semester.course_set.filter(state__in=[\"in_evaluation\", \"evaluated\", \"reviewed\", \"published\"]).prefetch_related(\"degrees\"))\n    else:\n        courses = list(semester.course_set.filter(state=\"published\").prefetch_related(\"degrees\"))\n\n    courses = [course for course in courses if course.can_user_see_course(request.user)]\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)\n    return render(request, \"results_semester_detail.html\", template_data)\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, semester=semester)\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') == 'true'  # if parameter is not given, show own view.\n\n    represented_users = list(request.user.represented_users.all())\n    represented_users.append(request.user)\n\n    # filter text answers\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, represented_users, 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    # remove empty sections\n    sections = [section for section in sections if section.results]\n\n    # 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,\n                                            {'total_votes': 0, 'sections': []})['sections'].append(section)\n\n            # Sum up all Sections for this contributor.\n            # If section is not a RatingResult:\n            # Add 1 as we assume it is a TextResult or something similar that should be displayed.\n            contributor_sections[section.contributor]['total_votes'] +=\\\n                sum([s.total_count if isinstance(s, RatingResult) else 1 for s in section.results])\n\n    # Show a warning if course is still in evaluation (for reviewer 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_reviewer 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            reviewer=request.user.is_reviewer,\n            contributor=course.is_user_contributor_or_delegate(request.user),\n            can_download_grades=request.user.can_download_grades,\n            public_view=public_view)\n    return render(request, \"results_course_detail.html\", template_data)\n\n\ndef user_can_see_text_answer(user, represented_users, text_answer, public_view=False):\n    if public_view:\n        return False\n    if text_answer.state not in COMMENT_STATES_REQUIRED_FOR_VISIBILITY:\n        return False\n    if user.is_reviewer:\n        return True\n\n    contributor = text_answer.contribution.contributor\n\n    if text_answer.is_private:\n        return contributor == user\n\n    if text_answer.is_published:\n        if text_answer.contribution.responsible:\n            return contributor == user or user in contributor.delegates.all()\n\n        if contributor in represented_users:\n            return True\n        if text_answer.contribution.course.contributions.filter(\n                contributor__in=represented_users, comment_visibility=Contribution.ALL_COMMENTS).exists():\n            return True\n        if text_answer.contribution.is_general and text_answer.contribution.course.contributions.filter(\n                contributor__in=represented_users, comment_visibility=Contribution.COURSE_COMMENTS).exists():\n            return True\n\n    return False\n", "path": "evap/results/views.py"}], "after_files": [{"content": "from collections import OrderedDict, namedtuple\n\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, render\nfrom django.contrib.auth.decorators import login_required\n\nfrom evap.evaluation.models import Semester, Degree, Contribution\nfrom evap.results.tools import calculate_results, calculate_average_grades_and_deviation, TextResult, RatingResult, COMMENT_STATES_REQUIRED_FOR_VISIBILITY\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    if request.user.is_reviewer:\n        courses = list(semester.course_set.filter(state__in=[\"in_evaluation\", \"evaluated\", \"reviewed\", \"published\"]).prefetch_related(\"degrees\"))\n    else:\n        courses = list(semester.course_set.filter(state=\"published\").prefetch_related(\"degrees\"))\n\n    courses = [course for course in courses if course.can_user_see_course(request.user)]\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)\n    return render(request, \"results_semester_detail.html\", template_data)\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, semester=semester)\n\n    if not course.can_user_see_results(request.user):\n        raise PermissionDenied\n\n    sections = calculate_results(course)\n\n    if request.user.is_staff or request.user.is_reviewer:\n        public_view = request.GET.get('public_view') != 'false'  # if parameter is not given, show public view.\n    else:\n        public_view = request.GET.get('public_view') == 'true'  # if parameter is not given, show own view.\n\n    represented_users = list(request.user.represented_users.all())\n    represented_users.append(request.user)\n\n    # filter text answers\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, represented_users, 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    # remove empty sections\n    sections = [section for section in sections if section.results]\n\n    # 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,\n                                            {'total_votes': 0, 'sections': []})['sections'].append(section)\n\n            # Sum up all Sections for this contributor.\n            # If section is not a RatingResult:\n            # Add 1 as we assume it is a TextResult or something similar that should be displayed.\n            contributor_sections[section.contributor]['total_votes'] +=\\\n                sum([s.total_count if isinstance(s, RatingResult) else 1 for s in section.results])\n\n    # Show a warning if course is still in evaluation (for reviewer 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_reviewer 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            reviewer=request.user.is_reviewer,\n            contributor=course.is_user_contributor_or_delegate(request.user),\n            can_download_grades=request.user.can_download_grades,\n            public_view=public_view)\n    return render(request, \"results_course_detail.html\", template_data)\n\n\ndef user_can_see_text_answer(user, represented_users, text_answer, public_view=False):\n    if public_view:\n        return False\n    if text_answer.state not in COMMENT_STATES_REQUIRED_FOR_VISIBILITY:\n        return False\n    if user.is_reviewer:\n        return True\n\n    contributor = text_answer.contribution.contributor\n\n    if text_answer.is_private:\n        return contributor == user\n\n    if text_answer.is_published:\n        if text_answer.contribution.responsible:\n            return contributor == user or user in contributor.delegates.all()\n\n        if contributor in represented_users:\n            return True\n        if text_answer.contribution.course.contributions.filter(\n                contributor__in=represented_users, comment_visibility=Contribution.ALL_COMMENTS).exists():\n            return True\n        if text_answer.contribution.is_general and text_answer.contribution.course.contributions.filter(\n                contributor__in=represented_users, comment_visibility=Contribution.COURSE_COMMENTS).exists():\n            return True\n\n    return False\n", "path": "evap/results/views.py"}]}