prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Include button to go back to previous level
  Thanks for the great project! While trying the website I wished I could go back one level, but there is only a button to go to the next level.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `hedyweb.py`
  Content:
  ```
  1 import collections
  2 import attr
  3 import glob
  4 from os import path
  5 
  6 from flask import jsonify, render_template, abort, redirect
  7 import courses
  8 from auth import current_user
  9 
  10 class Translations:
  11   def __init__(self):
  12     self.data = {}
  13     translations = glob.glob('coursedata/texts/*.yaml')
  14     for trans_file in translations:
  15       lang = path.splitext(path.basename(trans_file))[0]
  16       self.data[lang] = courses.load_yaml(trans_file)
  17 
  18   def get_translations(self, language, section):
  19     # Merge with English when lacking translations
  20     # Start from a defaultdict
  21     d = collections.defaultdict(lambda: '???')
  22     d.update(**self.data.get('en', {}).get(section, {}))
  23     d.update(**self.data.get(language, {}).get(section, {}))
  24     return d
  25 
  26 
  27 def render_assignment_editor(request, course, level_number, assignment_number, menu, translations, version, loaded_program):
  28   assignment = course.get_assignment(level_number, assignment_number)
  29   if not assignment:
  30     abort(404)
  31 
  32   arguments_dict = {}
  33 
  34   # Meta stuff
  35   arguments_dict['course'] = course
  36   arguments_dict['level_nr'] = str(level_number)
  37   arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'
  38   arguments_dict['lang'] = course.language
  39   arguments_dict['level'] = assignment.level
  40   arguments_dict['next_level'] = int(level_number) + 1 if int(level_number) < course.max_level() else None
  41   arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(assignment_number) < course.max_step(level_number) else None
  42   arguments_dict['menu'] = menu
  43   arguments_dict['latest'] = version
  44   arguments_dict['selected_page'] = 'code'
  45   arguments_dict['page_title'] = f'Level {level_number} – Hedy'
  46   arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]
  47   arguments_dict['auth'] = translations.data [course.language] ['Auth']
  48   arguments_dict['username'] = current_user(request) ['username']
  49   arguments_dict['loaded_program'] = loaded_program or ''
  50 
  51   # Translations
  52   arguments_dict.update(**translations.get_translations(course.language, 'ui'))
  53 
  54   # Actual assignment
  55   arguments_dict.update(**attr.asdict(assignment))
  56 
  57   return render_template("code-page.html", **arguments_dict)
  58 
  59 
  60 def render_assignment_docs(doc_type, course, level_number, assignment_number, menu, translations):
  61   assignment = course.get_assignment(level_number, assignment_number)
  62   if not assignment:
  63     abort(404)
  64 
  65   arguments_dict = {}
  66 
  67   # Meta stuff
  68   arguments_dict['course'] = course
  69   arguments_dict['level_nr'] = str(level_number)
  70   arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'
  71   arguments_dict['pagetitle'] = f'Level {level_number} - Hedy'
  72   arguments_dict['lang'] = course.language
  73   arguments_dict['selected_page'] = doc_type
  74   arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]
  75   arguments_dict['auth'] = translations.data [course.language] ['Auth']
  76 
  77   # Translations
  78   arguments_dict.update(**translations.get_translations(course.language, 'ui'))
  79 
  80   doc = course.docs.get(int(level_number), doc_type)
  81   if not doc:
  82     # Redirect to code page. Nasty 'import' here to work around
  83     # cyclic imports.
  84     import app
  85     return redirect(app.hedy_link(level_number, assignment_number))
  86 
  87   arguments_dict['mkd'] = doc.markdown
  88   arguments_dict['menu'] = menu
  89   arguments_dict['page_title'] = f'Level {level_number}.{assignment_number} – ' + doc.front_matter.get('title', '') + ' – Hedy'
  90 
  91   return render_template("per-level-text.html", **arguments_dict)
  92
  ```
  --- 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/hedyweb.py b/hedyweb.py
  --- a/hedyweb.py
  +++ b/hedyweb.py
  @@ -37,6 +37,7 @@
     arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'
     arguments_dict['lang'] = course.language
     arguments_dict['level'] = assignment.level
  +  arguments_dict['prev_level'] = int(level_number) - 1 if int(level_number) > 1 else None
     arguments_dict['next_level'] = int(level_number) + 1 if int(level_number) < course.max_level() else None
     arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(assignment_number) < course.max_step(level_number) else None
     arguments_dict['menu'] = menu
  
verification_info: {"golden_diff": "diff --git a/hedyweb.py b/hedyweb.py\n--- a/hedyweb.py\n+++ b/hedyweb.py\n@@ -37,6 +37,7 @@\n   arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'\n   arguments_dict['lang'] = course.language\n   arguments_dict['level'] = assignment.level\n+  arguments_dict['prev_level'] = int(level_number) - 1 if int(level_number) > 1 else None\n   arguments_dict['next_level'] = int(level_number) + 1 if int(level_number) < course.max_level() else None\n   arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(assignment_number) < course.max_step(level_number) else None\n   arguments_dict['menu'] = menu\n", "issue": "Include button to go back to previous level\nThanks for the great project! While trying the website I wished I could go back one level, but there is only a button to go to the next level.\n", "before_files": [{"content": "import collections\nimport attr\nimport glob\nfrom os import path\n\nfrom flask import jsonify, render_template, abort, redirect\nimport courses\nfrom auth import current_user\n\nclass Translations:\n  def __init__(self):\n    self.data = {}\n    translations = glob.glob('coursedata/texts/*.yaml')\n    for trans_file in translations:\n      lang = path.splitext(path.basename(trans_file))[0]\n      self.data[lang] = courses.load_yaml(trans_file)\n\n  def get_translations(self, language, section):\n    # Merge with English when lacking translations\n    # Start from a defaultdict\n    d = collections.defaultdict(lambda: '???')\n    d.update(**self.data.get('en', {}).get(section, {}))\n    d.update(**self.data.get(language, {}).get(section, {}))\n    return d\n\n\ndef render_assignment_editor(request, course, level_number, assignment_number, menu, translations, version, loaded_program):\n  assignment = course.get_assignment(level_number, assignment_number)\n  if not assignment:\n    abort(404)\n\n  arguments_dict = {}\n\n  # Meta stuff\n  arguments_dict['course'] = course\n  arguments_dict['level_nr'] = str(level_number)\n  arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'\n  arguments_dict['lang'] = course.language\n  arguments_dict['level'] = assignment.level\n  arguments_dict['next_level'] = int(level_number) + 1 if int(level_number) < course.max_level() else None\n  arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(assignment_number) < course.max_step(level_number) else None\n  arguments_dict['menu'] = menu\n  arguments_dict['latest'] = version\n  arguments_dict['selected_page'] = 'code'\n  arguments_dict['page_title'] = f'Level {level_number} \u2013 Hedy'\n  arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]\n  arguments_dict['auth'] = translations.data [course.language] ['Auth']\n  arguments_dict['username'] = current_user(request) ['username']\n  arguments_dict['loaded_program'] = loaded_program or ''\n\n  # Translations\n  arguments_dict.update(**translations.get_translations(course.language, 'ui'))\n\n  # Actual assignment\n  arguments_dict.update(**attr.asdict(assignment))\n\n  return render_template(\"code-page.html\", **arguments_dict)\n\n\ndef render_assignment_docs(doc_type, course, level_number, assignment_number, menu, translations):\n  assignment = course.get_assignment(level_number, assignment_number)\n  if not assignment:\n    abort(404)\n\n  arguments_dict = {}\n\n  # Meta stuff\n  arguments_dict['course'] = course\n  arguments_dict['level_nr'] = str(level_number)\n  arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'\n  arguments_dict['pagetitle'] = f'Level {level_number} - Hedy'\n  arguments_dict['lang'] = course.language\n  arguments_dict['selected_page'] = doc_type\n  arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]\n  arguments_dict['auth'] = translations.data [course.language] ['Auth']\n\n  # Translations\n  arguments_dict.update(**translations.get_translations(course.language, 'ui'))\n\n  doc = course.docs.get(int(level_number), doc_type)\n  if not doc:\n    # Redirect to code page. Nasty 'import' here to work around\n    # cyclic imports.\n    import app\n    return redirect(app.hedy_link(level_number, assignment_number))\n\n  arguments_dict['mkd'] = doc.markdown\n  arguments_dict['menu'] = menu\n  arguments_dict['page_title'] = f'Level {level_number}.{assignment_number} \u2013 ' + doc.front_matter.get('title', '') + ' \u2013 Hedy'\n\n  return render_template(\"per-level-text.html\", **arguments_dict)\n", "path": "hedyweb.py"}], "after_files": [{"content": "import collections\nimport attr\nimport glob\nfrom os import path\n\nfrom flask import jsonify, render_template, abort, redirect\nimport courses\nfrom auth import current_user\n\nclass Translations:\n  def __init__(self):\n    self.data = {}\n    translations = glob.glob('coursedata/texts/*.yaml')\n    for trans_file in translations:\n      lang = path.splitext(path.basename(trans_file))[0]\n      self.data[lang] = courses.load_yaml(trans_file)\n\n  def get_translations(self, language, section):\n    # Merge with English when lacking translations\n    # Start from a defaultdict\n    d = collections.defaultdict(lambda: '???')\n    d.update(**self.data.get('en', {}).get(section, {}))\n    d.update(**self.data.get(language, {}).get(section, {}))\n    return d\n\n\ndef render_assignment_editor(request, course, level_number, assignment_number, menu, translations, version, loaded_program):\n  assignment = course.get_assignment(level_number, assignment_number)\n  if not assignment:\n    abort(404)\n\n  arguments_dict = {}\n\n  # Meta stuff\n  arguments_dict['course'] = course\n  arguments_dict['level_nr'] = str(level_number)\n  arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'\n  arguments_dict['lang'] = course.language\n  arguments_dict['level'] = assignment.level\n  arguments_dict['prev_level'] = int(level_number) - 1 if int(level_number) > 1 else None\n  arguments_dict['next_level'] = int(level_number) + 1 if int(level_number) < course.max_level() else None\n  arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(assignment_number) < course.max_step(level_number) else None\n  arguments_dict['menu'] = menu\n  arguments_dict['latest'] = version\n  arguments_dict['selected_page'] = 'code'\n  arguments_dict['page_title'] = f'Level {level_number} \u2013 Hedy'\n  arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]\n  arguments_dict['auth'] = translations.data [course.language] ['Auth']\n  arguments_dict['username'] = current_user(request) ['username']\n  arguments_dict['loaded_program'] = loaded_program or ''\n\n  # Translations\n  arguments_dict.update(**translations.get_translations(course.language, 'ui'))\n\n  # Actual assignment\n  arguments_dict.update(**attr.asdict(assignment))\n\n  return render_template(\"code-page.html\", **arguments_dict)\n\n\ndef render_assignment_docs(doc_type, course, level_number, assignment_number, menu, translations):\n  assignment = course.get_assignment(level_number, assignment_number)\n  if not assignment:\n    abort(404)\n\n  arguments_dict = {}\n\n  # Meta stuff\n  arguments_dict['course'] = course\n  arguments_dict['level_nr'] = str(level_number)\n  arguments_dict['assignment_nr'] = assignment.step  # Give this a chance to be 'None'\n  arguments_dict['pagetitle'] = f'Level {level_number} - Hedy'\n  arguments_dict['lang'] = course.language\n  arguments_dict['selected_page'] = doc_type\n  arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]\n  arguments_dict['auth'] = translations.data [course.language] ['Auth']\n\n  # Translations\n  arguments_dict.update(**translations.get_translations(course.language, 'ui'))\n\n  doc = course.docs.get(int(level_number), doc_type)\n  if not doc:\n    # Redirect to code page. Nasty 'import' here to work around\n    # cyclic imports.\n    import app\n    return redirect(app.hedy_link(level_number, assignment_number))\n\n  arguments_dict['mkd'] = doc.markdown\n  arguments_dict['menu'] = menu\n  arguments_dict['page_title'] = f'Level {level_number}.{assignment_number} \u2013 ' + doc.front_matter.get('title', '') + ' \u2013 Hedy'\n\n  return render_template(\"per-level-text.html\", **arguments_dict)\n", "path": "hedyweb.py"}]}