Skip to content

Commit

Permalink
Add WuS notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
tmetzl committed Nov 5, 2024
1 parent ec2eb1c commit b64b192
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/build_and_push_all_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,36 @@ jobs:
e2xgrader_branch: ${{ inputs.e2xgrader_branch }}
secrets: inherit

wus_notebook:
needs: [datascience_notebook]
uses: ./.github/workflows/build_image.yml
with:
force_build: ${{ inputs.force_build || needs.datascience_notebook.outputs.did_build_image == 'true' }}
registry: ${{ inputs.registry }}
base_image_name: ${{ inputs.registry }}/digiklausur/docker-stacks/datascience-notebook
base_image_tag: ${{ inputs.tag }}
image_path: images/wus-notebook
image_name: wus-notebook
image_tag: ${{ inputs.tag }}
push: ${{ inputs.push }}
secrets: inherit

e2x_wus_notebook:
needs: [wus_notebook]
uses: ./.github/workflows/build_e2xgrader_images.yml
with:
force_build: ${{ inputs.force_build || needs.wus_notebook.outputs.did_build_image == 'true' }}
registry: ${{ inputs.registry }}
image_name: wus-notebook
image_tag: ${{ inputs.tag }}
base_image_name: ${{ inputs.registry }}/digiklausur/docker-stacks/wus-notebook
base_image_tag: ${{ inputs.tag }}
push: ${{ inputs.push }}
e2xgrader_installation_source: ${{ inputs.e2xgrader_installation_source }}
e2xgrader_version: ${{ inputs.e2xgrader_version }}
e2xgrader_branch: ${{ inputs.e2xgrader_branch }}
secrets: inherit

nlp_notebook:
needs: [ml_notebook]
uses: ./.github/workflows/build_image.yml
Expand Down
22 changes: 22 additions & 0 deletions images/wus-notebook/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ARG IMAGE_SOURCE=ghcr.io/digiklausur/docker-stacks/minimal-notebook:latest
FROM $IMAGE_SOURCE

LABEL maintainer="e2x project H-BRS <e2x@inf.h-brs.de>"
LABEL description="e2x notebook for statistics course"
LABEL org.opencontainers.image.description="e2x notebook for statistics course"
LABEL org.opencontainers.image.authors="e2x project H-BRS <e2x@inf.h-brs.de>"

USER root
# Copy nbgrader wus config
COPY configs/nbgrader_config.py /opt/conda/etc/jupyter/nbgrader_config.py
RUN chown root:"$NB_GID" /opt/conda/etc/jupyter/nbgrader_config.py &&\
chmod g+rwX /opt/conda/etc/jupyter/nbgrader_config.py

USER $NB_USER

# Disable execute time extension and enable highlight word
RUN jupyter nbextension disable --sys-prefix execute_time/ExecuteTime \
&& pip install --no-cache-dir jupyter_highlight_selected_word \
&& jupyter nbextension install --py --sys-prefix jupyter_highlight_selected_word \
&& jupyter nbextension enable --sys-prefix highlight_selected_word/main \
&& jupyter nbextension list
54 changes: 54 additions & 0 deletions images/wus-notebook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# e2x Data Science Notebook

TThis Docker image is a customized version of the [e2x Data Science Notebook](../datascience-notebook) image, with certain extensions specific to the WuS course at H-BRS installed.

## Build Args

The following build arg is available:

* `IMAGE_SOURCE`: The base image to use for the build. Defaults to `ghcr.io/digiklausur/docker-stacks/datascience-notebook:latest`.

## Description

This image is designed to provide a comprehensive Jupyter Notebook environment for data science tasks, building on top of the e2x Minimal Notebook image. It includes:

* All features from the e2x Minimal Notebook image
* A collection of popular Python data science libraries, including NumPy, Pandas, SciPy, Matplotlib, Scikit-learn, and more

## Versions

This images comes as a basic data science image or with `e2xgrader` installed and a specific mode activated.
For more information look at the [E2xGrader Notebook](../e2xgrader-notebook) image and the [e2xgrader](https://github.com/Digiklausur/e2xgrader) package.

* `wus-notebook`
+ Base WuS science image
* `wus-notebook-teacher`
+ Base data science image with `e2xgrader` teacher mode activated (includes grading tools)
* `wus-notebook-student`
+ Base data science image with `e2xgrader` student mode activated (includes extensions for students)
* `wus-notebook-exam`
+ Base data science image with `e2xgrader` student_exam mode activated (provides a restricted notebook for students in an exam)

## Usage

### Pull and Run

To pull and run the image use:

`docker run -p 8888:8888 ghcr.io/digiklausur/docker-stacks/wus-notebook:latest`

Available tags are `latest` and `dev`. Available registries are `quay.io` and `ghcr.io`.

### Build and Run

To build the image from the standard source, run:

`docker build -t wus-notebook:dev .`

To build the image from a custom source, run:

`docker build -t wus-notebook:dev . --build-arg="IMAGE_SOURCE=<your_base_image>:<your_tag>"`

To run the image, use:

`docker run -p 8888:8888 wus-notebook:dev`
102 changes: 102 additions & 0 deletions images/wus-notebook/configs/nbgrader_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from e2xgrader.config import configure_base
from nbgrader.preprocessors import GetGrades
from nbformat import NotebookNode
from nbconvert.exporters.exporter import ResourcesDict
from nbgrader.api import MissingEntry
from nbconvert.preprocessors import CSSHTMLHeaderPreprocessor
from e2xgrader.preprocessors import FilterTests

from e2xgrader.graders import MultipleChoiceGrader, CodeGrader, SingleChoiceGrader
from e2xgrader.utils.extra_cells import get_choices, get_instructor_choices
from traitlets import Unicode

class GetGradesWithUngradedComment(GetGrades):
"""
If a cell has not been graded, this processor adds a comment
saying "Unbewertet" to the cell
"""

ungraded_comment = Unicode(
"Unbewertet",
help="Comment to add to ungraded cells"
).tag(config=True)

def _get_comment(self, cell: NotebookNode, resources: ResourcesDict) -> None:
"""Graders can optionally add comments to the student's solutions, so
add the comment information into the database if it doesn't
already exist. It should NOT overwrite existing comments that
might have been added by a grader already.
"""
comment = self.gradebook.find_comment(
cell.metadata['nbgrader']['grade_id'],
self.notebook_id,
self.assignment_id,
self.student_id)

needs_manual_grade = False
try:
grade = self.gradebook.find_grade(
cell.metadata['nbgrader']['grade_id'],
self.notebook_id,
self.assignment_id,
self.student_id)
needs_manual_grade = grade.needs_manual_grade
except MissingEntry:
pass

comment = comment.comment

if comment is None:
comment = ""
else:
comment += "\n"

# save it in the notebook
if needs_manual_grade:
cell.metadata.nbgrader['comment'] = comment + self.ungraded_comment
else:
cell.metadata.nbgrader['comment'] = comment


class WuSMultipleChoiceGrader(MultipleChoiceGrader):

def determine_grade(self, cell, log=None):
'''
Grader for multiple choice questions
Only give full points if student did select all correct
answers and no incorrect answers
'''
max_points = float(cell.metadata['nbgrader']['points'])
student_choices = get_choices(cell)
instructor_choices = get_instructor_choices(cell)

# Return 0 points if the student did not select all correct answers
for choice in instructor_choices:
if choice not in student_choices:
return 0, max_points

# Return 0 points if the student did select an incorrect answer
for choice in student_choices:
if choice not in instructor_choices:
return 0, max_points

return max_points, max_points

c = get_config() # noqa: F821

c.GenerateFeedback.preprocessors = [
GetGradesWithUngradedComment,
FilterTests,
CSSHTMLHeaderPreprocessor
]

#print("Local config is", c)

c.SaveAutoGrades.graders = {
'multiplechoice': WuSMultipleChoiceGrader(),
'code': CodeGrader(),
'singlechoice': SingleChoiceGrader()
}

0 comments on commit b64b192

Please sign in to comment.