Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 38 additions & 24 deletions docs/source/instructor_guide/working_with_assignments.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,37 @@ In the overview window of the assignment, you will find many ways to monitor, gr

![Assignment Overview](../_static/assets/images/instructor_guide/assignment_overview.png)

## Assignment Lifecycle

![Assingment Status](../_static/assets/images/instructor_guide/assignment_lifecycle.png)

An assignment can have 3 states that can be switched between and represent the lifecycle of the assignment.

- Edit
: When first created, the assignment is in "Edit mode", where the assignment files can be added and edited.
In this stage, the assignment is not visible to students. However, when an instructor opens the student view ("Assignments" card in launcher), it will be displayed to them.
- Released
: The assignment is released to students and the students can work on it.
The released files are identical to the files in the release directory at the time of the release.
It is possible to undo the release and publish a new release. However, some students may have already pulled the old release.
In this case the students might have to reset their files and might loose progress, which has to be communicated.
In general, a re-release should be avoided.

:::{warning}
Revoking a released assignment may lead to diverging states of student files and submissions that fail auto-grading.
:::
- Completed
: The assignment is over and cannot be worked on anymore and new submissions will be rejected, but it is still visible.
This state can be revoked without any consideration and will return to a released state.

## Assignment Settings

![Assignment Settings](../_static/assets/images/instructor_guide/assignment_settings.png)

### Groups

You can assign assignments to a group you specify. This allows you to cluster assignments based on different criteria, e.g. the chapters of your lecture. Please note that each assignment can be assigned to only one group.

### Deadlines

As an instructor, you can set deadlines for assignments.
Expand All @@ -128,6 +155,14 @@ You can set a limit on the number of times students can submit an assignment.
**Submission Limits**:
You can define a maximum number of submissions for each assignment (e.g., students can submit up to 3 times). Once a student reaches this limit, they will no longer be able to make additional submissions unless you increase the limit for all students.

### Cell timeout

This field allows you to dynamically set the timeout of a cell per assignment in seconds. This means that the running time of each cell in the notebook(s) of the assignment will be limited by the value you specify. Please note that setting timeout for each cell separately is not possible.

### Whitelist File Patterns

By using `glob patterns` you can define which additional files can be submitted by the students. This allows you to have a better control over students' submissions and avoid getting unnecessary files from their side.

### Late Submissions

You can allow students to submit assignments after the deadline, with applied penalties on the total score.
Expand Down Expand Up @@ -156,28 +191,6 @@ It specifies the action taken when a user submits an assignment.
: The assignment is auto-graded and feedback is generated as soon as the student submits their assignment.
This requires that no manually graded cells are part of the assignment.

## Assignment Lifecycle

![Assingment Status](../_static/assets/images/instructor_guide/assignment_lifecycle.png)

An assignment can have 3 states that can be switched between and represent the lifecycle of the assignment.

- Edit
: When first created, the assignment is in "Edit mode", where the assignment files can be added and edited.
In this stage, the assignment is not visible to students. However, when an instructor opens the student view ("Assignments" card in launcher), it will be displayed to them.
- Released
: The assignment is released to students and the students can work on it.
The released files are identical to the files in the release directory at the time of the release.
It is possible to undo the release and publish a new release. However, some students may have already pulled the old release.
In this case the students might have to reset their files and might loose progress, which has to be communicated.
In general, a re-release should be avoided.

:::{warning}
Revoking a released assignment may lead to diverging states of student files and submissions that fail auto-grading.
:::
- Completed
: The assignment is over and cannot be worked on anymore and new submissions will be rejected, but it is still visible.
This state can be revoked without any consideration and will return to a released state.

## Grading Assignments

Expand All @@ -195,7 +208,6 @@ If manual grading is not needed or not wanted, it can be skipped.
The last step is feedback generation, at which point students will see their results.



## Manual Submissions

You have the ability to manually add submissions for students, even after the deadline has passed.
Expand All @@ -211,7 +223,9 @@ Following video illustrates the procedure:
![Manual Submission](../_static/assets/gifs/instructor_guide/manual_submission.gif)

### How To Grade Manual Answer Cells?
- Once a student submits their work, it will appear in the "Submissions" list. To manually grade a submission, it must first be automatically graded (this sets the necessary metadata for successful grading). If you selected "Automatic Grading" when creating the assignment, this will be done automatically and you may immediately proceed with manual grading. If you chose "No Automatic Grading," you must first select the submission and click "AUTOGRADE." Afterward, you will be able to manually grade the submission.
- Once a student submits their work, it will appear in the "Submissions" list.
If you selected "Automatic Grading" when creating the assignment, the submission has to be automatically graded and afterwards you may
immediately proceed with manual grading. If you chose "No Automatic Grading", you can just pull the submission right away and manually grade it.
- Click on submission in the Submission List and pull it. This will reveal files the student has submitted.
- Click on notebook that you want to manually grade and when the notebook opens up enable "Grading Mode".
- You can now assign points, leave comments or even give extra credits for the solution.
Expand Down
6 changes: 1 addition & 5 deletions grader_service/autograding/local_grader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import fnmatch
import json
import os
import shlex
import shutil
import subprocess
from datetime import datetime
Expand Down Expand Up @@ -258,10 +257,7 @@ def _get_whitelisted_files(self) -> List[str]:
if any(fnmatch.fnmatch(file_path, pattern) for pattern in file_patterns):
files_to_commit.append(file_path)

# escape filenames to handle special characters and whitespaces
escaped_files = [shlex.quote(f) for f in files_to_commit]

return escaped_files
return files_to_commit

def _set_properties(self) -> None:
"""
Expand Down
23 changes: 21 additions & 2 deletions grader_service/tests/autograding/test_local_grader.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,18 @@ def test_file_matching_with_patterns(mock_git, tmp_path, submission_123):
# Create test files in output directory
os.makedirs(executor.output_path, exist_ok=True)
test_dirs_and_files = [
(executor.output_path, ["Ex1.ipynb", "output.txt", "weird name.py", "config"]),
(
executor.output_path,
[
"Ex1.ipynb",
"Ex1.2.ipynb",
"output.txt",
"weird name.py",
"fi_le.ipynb",
"do:t.ipynb",
"config",
],
),
(executor.output_path + "/.git", ["config", "description", "HEAD"]),
(executor.output_path + "/bar", ["Ex2.ipynb", "data.gz", "config"]),
]
Expand All @@ -160,7 +171,15 @@ def test_file_matching_with_patterns(mock_git, tmp_path, submission_123):
# Get files to commit matching the whitelist patterns
files_to_commit = executor._get_whitelisted_files()

expected_files = {"Ex1.ipynb", "'weird name.py'", "bar/Ex2.ipynb", "bar/config"}
expected_files = {
"Ex1.ipynb",
"weird name.py",
"bar/Ex2.ipynb",
"bar/config",
"fi_le.ipynb",
"do:t.ipynb",
"Ex1.2.ipynb",
}
assert set(files_to_commit) == expected_files


Expand Down
2 changes: 1 addition & 1 deletion grader_service/tests/convert/converters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def _create_input_output_dirs(p: Path, input_notebooks=None):
if input_notebooks:
for n in input_notebooks:
shutil.copyfile(tests_dir / f"preprocessors/files/{n}", input_dir / n)

assert n in [f.name for f in input_dir.iterdir()]
return input_dir, output_dir


Expand Down
10 changes: 6 additions & 4 deletions grader_service/tests/convert/converters/test_autograde.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import shutil
from unittest.mock import patch

import pytest
from nbclient.client import NotebookClient

from grader_service.api.models.assignment_settings import AssignmentSettings
Expand All @@ -12,12 +13,13 @@
)


def test_autograde(tmp_path):
input_dir, output_dir = _create_input_output_dirs(tmp_path, ["simple.ipynb"])
@pytest.mark.parametrize("notebook_name", ["simple.ipynb", "with space.ipynb"])
def test_autograde(tmp_path, notebook_name):
input_dir, output_dir = _create_input_output_dirs(tmp_path, [notebook_name])

_generate_test_submission(input_dir, output_dir)

assert (output_dir / "simple.ipynb").exists()
assert (output_dir / notebook_name).exists()
assert (output_dir / "gradebook.json").exists()

output_dir2 = tmp_path / "output_dir2"
Expand All @@ -37,7 +39,7 @@ def test_autograde(tmp_path):
config=None,
).start()

assert (output_dir2 / "simple.ipynb").exists()
assert (output_dir2 / notebook_name).exists()
assert (output_dir2 / "gradebook.json").exists()


Expand Down
Loading
Loading