We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Display number of available reward points
On the staff page for reward point redemption events (`rewards/reward_point_redemption_events`), the total number of currently available (granted but not yet redeemed) number of reward points should be shown.
The information should be placed in the upper right corner (in the same line as the "Create new event" button, vertically centered) with the following text: `Available reward points: <number>`.

--- 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/rewards/views.py`
Content:
```
1 from datetime import datetime
2 
3 from django.contrib import messages
4 from django.core.exceptions import BadRequest, SuspiciousOperation
5 from django.http import HttpResponse
6 from django.shortcuts import get_object_or_404, redirect, render
7 from django.utils.translation import get_language
8 from django.utils.translation import gettext as _
9 from django.views.decorators.http import require_POST
10 
11 from evap.evaluation.auth import manager_required, reward_user_required
12 from evap.evaluation.models import Semester
13 from evap.evaluation.tools import AttachmentResponse, get_object_from_dict_pk_entry_or_logged_40x
14 from evap.rewards.exporters import RewardsExporter
15 from evap.rewards.forms import RewardPointRedemptionEventForm
16 from evap.rewards.models import (
17     NoPointsSelected,
18     NotEnoughPoints,
19     OutdatedRedemptionData,
20     RedemptionEventExpired,
21     RewardPointGranting,
22     RewardPointRedemption,
23     RewardPointRedemptionEvent,
24     SemesterActivation,
25 )
26 from evap.rewards.tools import grant_eligible_reward_points_for_semester, reward_points_of_user, save_redemptions
27 
28 
29 def redeem_reward_points(request):
30     redemptions = {}
31     try:
32         for key, value in request.POST.items():
33             if key.startswith("points-"):
34                 event_id = int(key.rpartition("-")[2])
35                 redemptions[event_id] = int(value)
36         previous_redeemed_points = int(request.POST["previous_redeemed_points"])
37     except (ValueError, KeyError, TypeError) as e:
38         raise BadRequest from e
39 
40     try:
41         save_redemptions(request, redemptions, previous_redeemed_points)
42         messages.success(request, _("You successfully redeemed your points."))
43     except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired, OutdatedRedemptionData) as error:
44         status_code = 400
45         if isinstance(error, NoPointsSelected):
46             error_string = _("You cannot redeem 0 points.")
47         elif isinstance(error, NotEnoughPoints):
48             error_string = _("You don't have enough reward points.")
49         elif isinstance(error, RedemptionEventExpired):
50             error_string = _("Sorry, the deadline for this event expired already.")
51         elif isinstance(error, OutdatedRedemptionData):
52             status_code = 409
53             error_string = _(
54                 "It appears that your browser sent multiple redemption requests. You can see all successful redemptions below."
55             )
56         messages.error(request, error_string)
57         return status_code
58     return 200
59 
60 
61 @reward_user_required
62 def index(request):
63     status = 200
64     if request.method == "POST":
65         status = redeem_reward_points(request)
66     total_points_available = reward_points_of_user(request.user)
67     reward_point_grantings = RewardPointGranting.objects.filter(user_profile=request.user)
68     reward_point_redemptions = RewardPointRedemption.objects.filter(user_profile=request.user)
69     events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by("date")
70 
71     reward_point_actions = []
72     for granting in reward_point_grantings:
73         reward_point_actions.append(
74             (granting.granting_time, _("Reward for") + " " + granting.semester.name, granting.value, "")
75         )
76     for redemption in reward_point_redemptions:
77         reward_point_actions.append((redemption.redemption_time, redemption.event.name, "", redemption.value))
78 
79     reward_point_actions.sort(key=lambda action: action[0], reverse=True)
80 
81     template_data = {
82         "reward_point_actions": reward_point_actions,
83         "total_points_available": total_points_available,
84         "total_points_spent": sum(redemption.value for redemption in reward_point_redemptions),
85         "events": events,
86     }
87     return render(request, "rewards_index.html", template_data, status=status)
88 
89 
90 @manager_required
91 def reward_point_redemption_events(request):
92     upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by("date")
93     past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by("-date")
94     template_data = {"upcoming_events": upcoming_events, "past_events": past_events}
95     return render(request, "rewards_reward_point_redemption_events.html", template_data)
96 
97 
98 @manager_required
99 def reward_point_redemption_event_create(request):
100     event = RewardPointRedemptionEvent()
101     form = RewardPointRedemptionEventForm(request.POST or None, instance=event)
102 
103     if form.is_valid():
104         form.save()
105         messages.success(request, _("Successfully created event."))
106         return redirect("rewards:reward_point_redemption_events")
107 
108     return render(request, "rewards_reward_point_redemption_event_form.html", {"form": form})
109 
110 
111 @manager_required
112 def reward_point_redemption_event_edit(request, event_id):
113     event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)
114     form = RewardPointRedemptionEventForm(request.POST or None, instance=event)
115 
116     if form.is_valid():
117         event = form.save()
118 
119         messages.success(request, _("Successfully updated event."))
120         return redirect("rewards:reward_point_redemption_events")
121 
122     return render(request, "rewards_reward_point_redemption_event_form.html", {"event": event, "form": form})
123 
124 
125 @require_POST
126 @manager_required
127 def reward_point_redemption_event_delete(request):
128     event = get_object_from_dict_pk_entry_or_logged_40x(RewardPointRedemptionEvent, request.POST, "event_id")
129 
130     if not event.can_delete:
131         raise SuspiciousOperation("Deleting redemption event not allowed")
132     event.delete()
133     return HttpResponse()  # 200 OK
134 
135 
136 @manager_required
137 def reward_point_redemption_event_export(request, event_id):
138     event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)
139 
140     filename = _("RewardPoints") + f"-{event.date}-{event.name}-{get_language()}.xls"
141     response = AttachmentResponse(filename, content_type="application/vnd.ms-excel")
142 
143     RewardsExporter().export(response, event.redemptions_by_user())
144 
145     return response
146 
147 
148 @require_POST
149 @manager_required
150 def semester_activation_edit(request, semester_id):
151     semester = get_object_or_404(Semester, id=semester_id)
152     status = request.POST.get("activation_status")
153     if status == "on":
154         active = True
155     elif status == "off":
156         active = False
157     else:
158         raise SuspiciousOperation("Invalid activation keyword")
159     SemesterActivation.objects.update_or_create(semester=semester, defaults={"is_active": active})
160     if active:
161         grant_eligible_reward_points_for_semester(request, semester)
162     return redirect("staff:semester_view", semester_id)
163
```
--- 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/rewards/views.py b/evap/rewards/views.py
--- a/evap/rewards/views.py
+++ b/evap/rewards/views.py
@@ -2,6 +2,7 @@
 
 from django.contrib import messages
 from django.core.exceptions import BadRequest, SuspiciousOperation
+from django.db.models import Sum
 from django.http import HttpResponse
 from django.shortcuts import get_object_or_404, redirect, render
 from django.utils.translation import get_language
@@ -91,7 +92,14 @@
 def reward_point_redemption_events(request):
     upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by("date")
     past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by("-date")
-    template_data = {"upcoming_events": upcoming_events, "past_events": past_events}
+    total_points_granted = RewardPointGranting.objects.aggregate(Sum("value"))["value__sum"] or 0
+    total_points_redeemed = RewardPointRedemption.objects.aggregate(Sum("value"))["value__sum"] or 0
+    total_points_available = total_points_granted - total_points_redeemed
+    template_data = {
+        "upcoming_events": upcoming_events,
+        "past_events": past_events,
+        "total_points_available": total_points_available,
+    }
     return render(request, "rewards_reward_point_redemption_events.html", template_data)

{"golden_diff": "diff --git a/evap/rewards/views.py b/evap/rewards/views.py\n--- a/evap/rewards/views.py\n+++ b/evap/rewards/views.py\n@@ -2,6 +2,7 @@\n \n from django.contrib import messages\n from django.core.exceptions import BadRequest, SuspiciousOperation\n+from django.db.models import Sum\n from django.http import HttpResponse\n from django.shortcuts import get_object_or_404, redirect, render\n from django.utils.translation import get_language\n@@ -91,7 +92,14 @@\n def reward_point_redemption_events(request):\n     upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by(\"date\")\n     past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by(\"-date\")\n-    template_data = {\"upcoming_events\": upcoming_events, \"past_events\": past_events}\n+    total_points_granted = RewardPointGranting.objects.aggregate(Sum(\"value\"))[\"value__sum\"] or 0\n+    total_points_redeemed = RewardPointRedemption.objects.aggregate(Sum(\"value\"))[\"value__sum\"] or 0\n+    total_points_available = total_points_granted - total_points_redeemed\n+    template_data = {\n+        \"upcoming_events\": upcoming_events,\n+        \"past_events\": past_events,\n+        \"total_points_available\": total_points_available,\n+    }\n     return render(request, \"rewards_reward_point_redemption_events.html\", template_data)\n", "issue": "Display number of available reward points\nOn the staff page for reward point redemption events (`rewards/reward_point_redemption_events`), the total number of currently available (granted but not yet redeemed) number of reward points should be shown.\r\nThe information should be placed in the upper right corner (in the same line as the \"Create new event\" button, vertically centered) with the following text: `Available reward points: <number>`.\n", "before_files": [{"content": "from datetime import datetime\n\nfrom django.contrib import messages\nfrom django.core.exceptions import BadRequest, SuspiciousOperation\nfrom django.http import HttpResponse\nfrom django.shortcuts import get_object_or_404, redirect, render\nfrom django.utils.translation import get_language\nfrom django.utils.translation import gettext as _\nfrom django.views.decorators.http import require_POST\n\nfrom evap.evaluation.auth import manager_required, reward_user_required\nfrom evap.evaluation.models import Semester\nfrom evap.evaluation.tools import AttachmentResponse, get_object_from_dict_pk_entry_or_logged_40x\nfrom evap.rewards.exporters import RewardsExporter\nfrom evap.rewards.forms import RewardPointRedemptionEventForm\nfrom evap.rewards.models import (\n    NoPointsSelected,\n    NotEnoughPoints,\n    OutdatedRedemptionData,\n    RedemptionEventExpired,\n    RewardPointGranting,\n    RewardPointRedemption,\n    RewardPointRedemptionEvent,\n    SemesterActivation,\n)\nfrom evap.rewards.tools import grant_eligible_reward_points_for_semester, reward_points_of_user, save_redemptions\n\n\ndef redeem_reward_points(request):\n    redemptions = {}\n    try:\n        for key, value in request.POST.items():\n            if key.startswith(\"points-\"):\n                event_id = int(key.rpartition(\"-\")[2])\n                redemptions[event_id] = int(value)\n        previous_redeemed_points = int(request.POST[\"previous_redeemed_points\"])\n    except (ValueError, KeyError, TypeError) as e:\n        raise BadRequest from e\n\n    try:\n        save_redemptions(request, redemptions, previous_redeemed_points)\n        messages.success(request, _(\"You successfully redeemed your points.\"))\n    except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired, OutdatedRedemptionData) as error:\n        status_code = 400\n        if isinstance(error, NoPointsSelected):\n            error_string = _(\"You cannot redeem 0 points.\")\n        elif isinstance(error, NotEnoughPoints):\n            error_string = _(\"You don't have enough reward points.\")\n        elif isinstance(error, RedemptionEventExpired):\n            error_string = _(\"Sorry, the deadline for this event expired already.\")\n        elif isinstance(error, OutdatedRedemptionData):\n            status_code = 409\n            error_string = _(\n                \"It appears that your browser sent multiple redemption requests. You can see all successful redemptions below.\"\n            )\n        messages.error(request, error_string)\n        return status_code\n    return 200\n\n\n@reward_user_required\ndef index(request):\n    status = 200\n    if request.method == \"POST\":\n        status = redeem_reward_points(request)\n    total_points_available = reward_points_of_user(request.user)\n    reward_point_grantings = RewardPointGranting.objects.filter(user_profile=request.user)\n    reward_point_redemptions = RewardPointRedemption.objects.filter(user_profile=request.user)\n    events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by(\"date\")\n\n    reward_point_actions = []\n    for granting in reward_point_grantings:\n        reward_point_actions.append(\n            (granting.granting_time, _(\"Reward for\") + \" \" + granting.semester.name, granting.value, \"\")\n        )\n    for redemption in reward_point_redemptions:\n        reward_point_actions.append((redemption.redemption_time, redemption.event.name, \"\", redemption.value))\n\n    reward_point_actions.sort(key=lambda action: action[0], reverse=True)\n\n    template_data = {\n        \"reward_point_actions\": reward_point_actions,\n        \"total_points_available\": total_points_available,\n        \"total_points_spent\": sum(redemption.value for redemption in reward_point_redemptions),\n        \"events\": events,\n    }\n    return render(request, \"rewards_index.html\", template_data, status=status)\n\n\n@manager_required\ndef reward_point_redemption_events(request):\n    upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by(\"date\")\n    past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by(\"-date\")\n    template_data = {\"upcoming_events\": upcoming_events, \"past_events\": past_events}\n    return render(request, \"rewards_reward_point_redemption_events.html\", template_data)\n\n\n@manager_required\ndef reward_point_redemption_event_create(request):\n    event = RewardPointRedemptionEvent()\n    form = RewardPointRedemptionEventForm(request.POST or None, instance=event)\n\n    if form.is_valid():\n        form.save()\n        messages.success(request, _(\"Successfully created event.\"))\n        return redirect(\"rewards:reward_point_redemption_events\")\n\n    return render(request, \"rewards_reward_point_redemption_event_form.html\", {\"form\": form})\n\n\n@manager_required\ndef reward_point_redemption_event_edit(request, event_id):\n    event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)\n    form = RewardPointRedemptionEventForm(request.POST or None, instance=event)\n\n    if form.is_valid():\n        event = form.save()\n\n        messages.success(request, _(\"Successfully updated event.\"))\n        return redirect(\"rewards:reward_point_redemption_events\")\n\n    return render(request, \"rewards_reward_point_redemption_event_form.html\", {\"event\": event, \"form\": form})\n\n\n@require_POST\n@manager_required\ndef reward_point_redemption_event_delete(request):\n    event = get_object_from_dict_pk_entry_or_logged_40x(RewardPointRedemptionEvent, request.POST, \"event_id\")\n\n    if not event.can_delete:\n        raise SuspiciousOperation(\"Deleting redemption event not allowed\")\n    event.delete()\n    return HttpResponse()  # 200 OK\n\n\n@manager_required\ndef reward_point_redemption_event_export(request, event_id):\n    event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)\n\n    filename = _(\"RewardPoints\") + f\"-{event.date}-{event.name}-{get_language()}.xls\"\n    response = AttachmentResponse(filename, content_type=\"application/vnd.ms-excel\")\n\n    RewardsExporter().export(response, event.redemptions_by_user())\n\n    return response\n\n\n@require_POST\n@manager_required\ndef semester_activation_edit(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    status = request.POST.get(\"activation_status\")\n    if status == \"on\":\n        active = True\n    elif status == \"off\":\n        active = False\n    else:\n        raise SuspiciousOperation(\"Invalid activation keyword\")\n    SemesterActivation.objects.update_or_create(semester=semester, defaults={\"is_active\": active})\n    if active:\n        grant_eligible_reward_points_for_semester(request, semester)\n    return redirect(\"staff:semester_view\", semester_id)\n", "path": "evap/rewards/views.py"}], "after_files": [{"content": "from datetime import datetime\n\nfrom django.contrib import messages\nfrom django.core.exceptions import BadRequest, SuspiciousOperation\nfrom django.db.models import Sum\nfrom django.http import HttpResponse\nfrom django.shortcuts import get_object_or_404, redirect, render\nfrom django.utils.translation import get_language\nfrom django.utils.translation import gettext as _\nfrom django.views.decorators.http import require_POST\n\nfrom evap.evaluation.auth import manager_required, reward_user_required\nfrom evap.evaluation.models import Semester\nfrom evap.evaluation.tools import AttachmentResponse, get_object_from_dict_pk_entry_or_logged_40x\nfrom evap.rewards.exporters import RewardsExporter\nfrom evap.rewards.forms import RewardPointRedemptionEventForm\nfrom evap.rewards.models import (\n    NoPointsSelected,\n    NotEnoughPoints,\n    OutdatedRedemptionData,\n    RedemptionEventExpired,\n    RewardPointGranting,\n    RewardPointRedemption,\n    RewardPointRedemptionEvent,\n    SemesterActivation,\n)\nfrom evap.rewards.tools import grant_eligible_reward_points_for_semester, reward_points_of_user, save_redemptions\n\n\ndef redeem_reward_points(request):\n    redemptions = {}\n    try:\n        for key, value in request.POST.items():\n            if key.startswith(\"points-\"):\n                event_id = int(key.rpartition(\"-\")[2])\n                redemptions[event_id] = int(value)\n        previous_redeemed_points = int(request.POST[\"previous_redeemed_points\"])\n    except (ValueError, KeyError, TypeError) as e:\n        raise BadRequest from e\n\n    try:\n        save_redemptions(request, redemptions, previous_redeemed_points)\n        messages.success(request, _(\"You successfully redeemed your points.\"))\n    except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired, OutdatedRedemptionData) as error:\n        status_code = 400\n        if isinstance(error, NoPointsSelected):\n            error_string = _(\"You cannot redeem 0 points.\")\n        elif isinstance(error, NotEnoughPoints):\n            error_string = _(\"You don't have enough reward points.\")\n        elif isinstance(error, RedemptionEventExpired):\n            error_string = _(\"Sorry, the deadline for this event expired already.\")\n        elif isinstance(error, OutdatedRedemptionData):\n            status_code = 409\n            error_string = _(\n                \"It appears that your browser sent multiple redemption requests. You can see all successful redemptions below.\"\n            )\n        messages.error(request, error_string)\n        return status_code\n    return 200\n\n\n@reward_user_required\ndef index(request):\n    status = 200\n    if request.method == \"POST\":\n        status = redeem_reward_points(request)\n    total_points_available = reward_points_of_user(request.user)\n    reward_point_grantings = RewardPointGranting.objects.filter(user_profile=request.user)\n    reward_point_redemptions = RewardPointRedemption.objects.filter(user_profile=request.user)\n    events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by(\"date\")\n\n    reward_point_actions = []\n    for granting in reward_point_grantings:\n        reward_point_actions.append(\n            (granting.granting_time, _(\"Reward for\") + \" \" + granting.semester.name, granting.value, \"\")\n        )\n    for redemption in reward_point_redemptions:\n        reward_point_actions.append((redemption.redemption_time, redemption.event.name, \"\", redemption.value))\n\n    reward_point_actions.sort(key=lambda action: action[0], reverse=True)\n\n    template_data = {\n        \"reward_point_actions\": reward_point_actions,\n        \"total_points_available\": total_points_available,\n        \"total_points_spent\": sum(redemption.value for redemption in reward_point_redemptions),\n        \"events\": events,\n    }\n    return render(request, \"rewards_index.html\", template_data, status=status)\n\n\n@manager_required\ndef reward_point_redemption_events(request):\n    upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by(\"date\")\n    past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by(\"-date\")\n    total_points_granted = RewardPointGranting.objects.aggregate(Sum(\"value\"))[\"value__sum\"] or 0\n    total_points_redeemed = RewardPointRedemption.objects.aggregate(Sum(\"value\"))[\"value__sum\"] or 0\n    total_points_available = total_points_granted - total_points_redeemed\n    template_data = {\n        \"upcoming_events\": upcoming_events,\n        \"past_events\": past_events,\n        \"total_points_available\": total_points_available,\n    }\n    return render(request, \"rewards_reward_point_redemption_events.html\", template_data)\n\n\n@manager_required\ndef reward_point_redemption_event_create(request):\n    event = RewardPointRedemptionEvent()\n    form = RewardPointRedemptionEventForm(request.POST or None, instance=event)\n\n    if form.is_valid():\n        form.save()\n        messages.success(request, _(\"Successfully created event.\"))\n        return redirect(\"rewards:reward_point_redemption_events\")\n\n    return render(request, \"rewards_reward_point_redemption_event_form.html\", {\"form\": form})\n\n\n@manager_required\ndef reward_point_redemption_event_edit(request, event_id):\n    event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)\n    form = RewardPointRedemptionEventForm(request.POST or None, instance=event)\n\n    if form.is_valid():\n        event = form.save()\n\n        messages.success(request, _(\"Successfully updated event.\"))\n        return redirect(\"rewards:reward_point_redemption_events\")\n\n    return render(request, \"rewards_reward_point_redemption_event_form.html\", {\"event\": event, \"form\": form})\n\n\n@require_POST\n@manager_required\ndef reward_point_redemption_event_delete(request):\n    event = get_object_from_dict_pk_entry_or_logged_40x(RewardPointRedemptionEvent, request.POST, \"event_id\")\n\n    if not event.can_delete:\n        raise SuspiciousOperation(\"Deleting redemption event not allowed\")\n    event.delete()\n    return HttpResponse()  # 200 OK\n\n\n@manager_required\ndef reward_point_redemption_event_export(request, event_id):\n    event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)\n\n    filename = _(\"RewardPoints\") + f\"-{event.date}-{event.name}-{get_language()}.xls\"\n    response = AttachmentResponse(filename, content_type=\"application/vnd.ms-excel\")\n\n    RewardsExporter().export(response, event.redemptions_by_user())\n\n    return response\n\n\n@require_POST\n@manager_required\ndef semester_activation_edit(request, semester_id):\n    semester = get_object_or_404(Semester, id=semester_id)\n    status = request.POST.get(\"activation_status\")\n    if status == \"on\":\n        active = True\n    elif status == \"off\":\n        active = False\n    else:\n        raise SuspiciousOperation(\"Invalid activation keyword\")\n    SemesterActivation.objects.update_or_create(semester=semester, defaults={\"is_active\": active})\n    if active:\n        grant_eligible_reward_points_for_semester(request, semester)\n    return redirect(\"staff:semester_view\", semester_id)\n", "path": "evap/rewards/views.py"}]}