prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Replace reward point redemption dropdown with number input field
  If a user selects an option, a new line is added and the selection spans two rows. This looks wrong.
  
  A user can insert custom options. If the user inputs something invalid like "abcdef" or an empty string, only parts of "Please select"-placeholder is visible. This looks wrong as well.
  Replace reward point redemption dropdown with number input field
  If a user selects an option, a new line is added and the selection spans two rows. This looks wrong.
  
  A user can insert custom options. If the user inputs something invalid like "abcdef" or an empty string, only parts of "Please select"-placeholder is visible. This looks wrong as well.
  
  --- 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     RedemptionEventExpired,
  20     RewardPointGranting,
  21     RewardPointRedemption,
  22     RewardPointRedemptionEvent,
  23     SemesterActivation,
  24 )
  25 from evap.rewards.tools import grant_eligible_reward_points_for_semester, reward_points_of_user, save_redemptions
  26 from evap.staff.views import semester_view
  27 
  28 
  29 @reward_user_required
  30 def index(request):
  31     if request.method == "POST":
  32         redemptions = {}
  33         try:
  34             for key, value in request.POST.items():
  35                 if key.startswith("points-"):
  36                     event_id = int(key.rpartition("-")[2])
  37                     redemptions[event_id] = int(value)
  38         except ValueError as e:
  39             raise BadRequest from e
  40 
  41         try:
  42             save_redemptions(request, redemptions)
  43             messages.success(request, _("You successfully redeemed your points."))
  44         except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired) as error:
  45             messages.warning(request, error)
  46 
  47     total_points_available = reward_points_of_user(request.user)
  48     reward_point_grantings = RewardPointGranting.objects.filter(user_profile=request.user)
  49     reward_point_redemptions = RewardPointRedemption.objects.filter(user_profile=request.user)
  50     events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by("date")
  51 
  52     reward_point_actions = []
  53     for granting in reward_point_grantings:
  54         reward_point_actions.append(
  55             (granting.granting_time, _("Reward for") + " " + granting.semester.name, granting.value, "")
  56         )
  57     for redemption in reward_point_redemptions:
  58         reward_point_actions.append((redemption.redemption_time, redemption.event.name, "", redemption.value))
  59 
  60     reward_point_actions.sort(key=lambda action: action[0], reverse=True)
  61 
  62     template_data = dict(
  63         reward_point_actions=reward_point_actions,
  64         total_points_available=total_points_available,
  65         events=events,
  66         point_selection=range(0, total_points_available + 1),
  67     )
  68     return render(request, "rewards_index.html", template_data)
  69 
  70 
  71 @manager_required
  72 def reward_point_redemption_events(request):
  73     upcoming_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__gte=datetime.now()).order_by("date")
  74     past_events = RewardPointRedemptionEvent.objects.filter(redeem_end_date__lt=datetime.now()).order_by("-date")
  75     template_data = dict(upcoming_events=upcoming_events, past_events=past_events)
  76     return render(request, "rewards_reward_point_redemption_events.html", template_data)
  77 
  78 
  79 @manager_required
  80 def reward_point_redemption_event_create(request):
  81     event = RewardPointRedemptionEvent()
  82     form = RewardPointRedemptionEventForm(request.POST or None, instance=event)
  83 
  84     if form.is_valid():
  85         form.save()
  86         messages.success(request, _("Successfully created event."))
  87         return redirect("rewards:reward_point_redemption_events")
  88 
  89     return render(request, "rewards_reward_point_redemption_event_form.html", dict(form=form))
  90 
  91 
  92 @manager_required
  93 def reward_point_redemption_event_edit(request, event_id):
  94     event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)
  95     form = RewardPointRedemptionEventForm(request.POST or None, instance=event)
  96 
  97     if form.is_valid():
  98         event = form.save()
  99 
  100         messages.success(request, _("Successfully updated event."))
  101         return redirect("rewards:reward_point_redemption_events")
  102 
  103     return render(request, "rewards_reward_point_redemption_event_form.html", dict(event=event, form=form))
  104 
  105 
  106 @require_POST
  107 @manager_required
  108 def reward_point_redemption_event_delete(request):
  109     event = get_object_from_dict_pk_entry_or_logged_40x(RewardPointRedemptionEvent, request.POST, "event_id")
  110 
  111     if not event.can_delete:
  112         raise SuspiciousOperation("Deleting redemption event not allowed")
  113     event.delete()
  114     return HttpResponse()  # 200 OK
  115 
  116 
  117 @manager_required
  118 def reward_point_redemption_event_export(request, event_id):
  119     event = get_object_or_404(RewardPointRedemptionEvent, id=event_id)
  120 
  121     filename = _("RewardPoints") + f"-{event.date}-{event.name}-{get_language()}.xls"
  122     response = AttachmentResponse(filename, content_type="application/vnd.ms-excel")
  123 
  124     RewardsExporter().export(response, event.redemptions_by_user())
  125 
  126     return response
  127 
  128 
  129 @manager_required
  130 def semester_activation(request, semester_id, active):
  131     semester = get_object_or_404(Semester, id=semester_id)
  132     active = active == "on"
  133 
  134     SemesterActivation.objects.update_or_create(semester=semester, defaults={"is_active": active})
  135     if active:
  136         grant_eligible_reward_points_for_semester(request, semester)
  137 
  138     return semester_view(request=request, semester_id=semester_id)
  139
  ```
  --- 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/rewards/views.py b/evap/rewards/views.py
  --- a/evap/rewards/views.py
  +++ b/evap/rewards/views.py
  @@ -63,7 +63,6 @@
           reward_point_actions=reward_point_actions,
           total_points_available=total_points_available,
           events=events,
  -        point_selection=range(0, total_points_available + 1),
       )
       return render(request, "rewards_index.html", template_data)
  
verification_info: {"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@@ -63,7 +63,6 @@\n         reward_point_actions=reward_point_actions,\n         total_points_available=total_points_available,\n         events=events,\n-        point_selection=range(0, total_points_available + 1),\n     )\n     return render(request, \"rewards_index.html\", template_data)\n", "issue": "Replace reward point redemption dropdown with number input field\nIf a user selects an option, a new line is added and the selection spans two rows. This looks wrong.\r\n\r\nA user can insert custom options. If the user inputs something invalid like \"abcdef\" or an empty string, only parts of \"Please select\"-placeholder is visible. This looks wrong as well.\nReplace reward point redemption dropdown with number input field\nIf a user selects an option, a new line is added and the selection spans two rows. This looks wrong.\r\n\r\nA user can insert custom options. If the user inputs something invalid like \"abcdef\" or an empty string, only parts of \"Please select\"-placeholder is visible. This looks wrong as well.\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    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\nfrom evap.staff.views import semester_view\n\n\n@reward_user_required\ndef index(request):\n    if request.method == \"POST\":\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        except ValueError as e:\n            raise BadRequest from e\n\n        try:\n            save_redemptions(request, redemptions)\n            messages.success(request, _(\"You successfully redeemed your points.\"))\n        except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired) as error:\n            messages.warning(request, error)\n\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 = dict(\n        reward_point_actions=reward_point_actions,\n        total_points_available=total_points_available,\n        events=events,\n        point_selection=range(0, total_points_available + 1),\n    )\n    return render(request, \"rewards_index.html\", template_data)\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 = dict(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\", dict(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\", dict(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@manager_required\ndef semester_activation(request, semester_id, active):\n    semester = get_object_or_404(Semester, id=semester_id)\n    active = active == \"on\"\n\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\n    return semester_view(request=request, semester_id=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.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    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\nfrom evap.staff.views import semester_view\n\n\n@reward_user_required\ndef index(request):\n    if request.method == \"POST\":\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        except ValueError as e:\n            raise BadRequest from e\n\n        try:\n            save_redemptions(request, redemptions)\n            messages.success(request, _(\"You successfully redeemed your points.\"))\n        except (NoPointsSelected, NotEnoughPoints, RedemptionEventExpired) as error:\n            messages.warning(request, error)\n\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 = dict(\n        reward_point_actions=reward_point_actions,\n        total_points_available=total_points_available,\n        events=events,\n    )\n    return render(request, \"rewards_index.html\", template_data)\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 = dict(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\", dict(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\", dict(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@manager_required\ndef semester_activation(request, semester_id, active):\n    semester = get_object_or_404(Semester, id=semester_id)\n    active = active == \"on\"\n\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\n    return semester_view(request=request, semester_id=semester_id)\n", "path": "evap/rewards/views.py"}]}