diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..0f81258 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,26 @@ +name: Lint + +on: + push: + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + cache: pip + + - name: Install dependencies + run: | + pip install -r requirements.txt -r dev-requirements.txt types-jsonschema + + - name: Run pre-commit hooks + run: | + pre-commit run --all-files diff --git a/.github/workflows/update-metadata.yml b/.github/workflows/update-metadata.yml index 5e49502..a190623 100644 --- a/.github/workflows/update-metadata.yml +++ b/.github/workflows/update-metadata.yml @@ -1,17 +1,21 @@ name: Update Metadata on: - push: + workflow_run: + workflows: ["Lint"] + types: + - completed workflow_dispatch: # Prevent infinite loops when workflow commits changes concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.ref }} cancel-in-progress: true jobs: update-metadata: runs-on: ubuntu-latest + if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} # Need write permission to push changes permissions: contents: write @@ -19,15 +23,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: ${{ github.ref }} + ref: ${{ github.event.workflow_run.head_sha || github.ref }} fetch-depth: 0 - name: Extract version from tag (if triggered by tag) id: extract_version run: | - if [[ "$GITHUB_REF" == refs/tags/v* ]]; then - TAG_NAME=${GITHUB_REF#refs/tags/} - # Remove 'v' prefix if present (v1.0.0 -> 1.0.0) + REF="${{ github.event.workflow_run.head_branch || github.ref }}" + if [[ "$REF" == refs/tags/v* ]] || git tag --points-at HEAD | grep -q '^v'; then + TAG_NAME=$(git tag --points-at HEAD | grep '^v' | head -1) + if [[ -z "$TAG_NAME" && "$REF" == refs/tags/v* ]]; then + TAG_NAME=${REF#refs/tags/} + fi VERSION=${TAG_NAME#v} echo "version=$VERSION" >> $GITHUB_OUTPUT echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT @@ -35,7 +42,7 @@ jobs: echo "Triggered by version tag: $TAG_NAME (version: $VERSION)" else echo "is_tag=false" >> $GITHUB_OUTPUT - echo "Triggered by regular push to: $GITHUB_REF" + echo "Triggered by regular push to: $REF" fi - name: Set up Python diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..46aa79c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +repos: + - repo: local + hooks: + - id: ruff + name: ruff + entry: bash -c 'ruff check --fix --target-version=py$(cat .python-version | tr -d "\n." ) "$@"' -- + language: system + types: [python] + + - id: ruff-format + name: ruff-format + entry: bash -c 'ruff format --target-version=py$(cat .python-version | tr -d "\n.") "$@"' -- + language: system + types: [python] + + - id: mypy + name: mypy + entry: bash -c 'mypy --python-version=$(cat .python-version | tr -d "\n") "$@"' -- + language: system + types: [python] diff --git a/.zenodo.json b/.zenodo.json index 9efa954..9b52cf1 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -17,7 +17,7 @@ "affiliation": "Universität Potsdam" } ], - "description": "

Dieses interaktive Lehrbuch führt in die Erstellung von Open Educational Resources (OER) nach den Empfehlungen und Vorgaben des Datenkompetenzzentrumgs QUADRIGA als Jupyter Book ein. Diese Empfehlungen und Vorgaben sind einerseits inhaltlicher und didaktischer andererseits technischer Natur. Diese OER richtet sich vorrangig an OER-Erstellende und kann als Startpunkt (Template) für die Erstellung eigener OER genutzt werden. Einzelne (Unter-)Kapitel bieten zudem Erläuterungen zu Funktionalitäten für Lernende.

\n

Dieses interaktive Lehrbuch kann als Web-Version verwendet, zur individuellen Anpassung heruntergeladen werden und steht darüber hinaus auch auf GitHub zur Verfügung.

\n

Die QUADRIGA-OER sind nach einem einheitlichen Template gestaltet, werden nach einem standardisierten Verfahren qualitätsgeprüft und mit Metadaten nach dem QUADRIGA-Metadatenschema ausgezeichnet.

\n
QUADRIGA Datenkompetenzzentrum
\n

QUADRIGA ist das Datenkompetenzzentrum der Wissenschaftsregion Berlin-Brandenburg. Für die beiden Anwendungsdomänen Digital Humanities und Verwaltungswissenschaft entstehen unter der Einbindung der Expertise der beiden Disziplinen Informatik und Informationswissenschaft Selbstlernangebote, die als OER in Form von Jupyter Books zur freien Nachnutzung zur Verfügung gestellt werden. Um den Forschungsprozess möglichst realistisch abzubilden, basieren die OER auf Fallstudien, denen wiederum ein eigens für das Projekt entwickeltes Datenkompetenzframework zugrunde liegt. Die Fallstudien nehmen drei für die Anwendungsdomänen repräsentativen Datentypen in den Blick: Bewegtes Bild, Tabelle und Text.

\n

Zu den Zielgruppen von QUADRIGA zählen insbesondere promovierende und promovierte Wissenschaftler*innen der genannten Disziplinen, die den Umgang mit digitalen Daten, Methoden und Werkzeugen erlernen und weiterentwickeln wollen.

\n

QUADRIGA ist eins von 11 Datenkompetenzzentren in Deutschland und wird vom Bundesministerium für Forschung, Technologie und Raumfahrt (BMFTR) und von der Europäischen Union im Rahmen von NextGenerationEU finanziert. Zu den Verbundpartnern zählen:\n

\n

\n\n

Mehr zum Aufbau und zur Umsetzung des Projekts können Sie im Umsetzungskonzept erfahren.

\n\n

Weitere Informationen sowie Publikationen finden Sie auf der Webseite, in der Zenodo-Community und der GitHub-Organisation des Projekts.

\n", + "description": "

Dieses interaktive Lehrbuch führt in die Erstellung von Open Educational Resources (OER) nach den Empfehlungen und Vorgaben des Datenkompetenzzentrumgs QUADRIGA als Jupyter Book ein. Diese Empfehlungen und Vorgaben sind einerseits inhaltlicher und didaktischer andererseits technischer Natur. Diese OER richtet sich vorrangig an OER-Erstellende und kann als Startpunkt (Template) für die Erstellung eigener OER genutzt werden. Einzelne (Unter-)Kapitel bieten zudem Erläuterungen zu Funktionalitäten für Lernende.

\n

Dieses interaktive Lehrbuch kann als Web-Version verwendet, zur individuellen Anpassung heruntergeladen werden und steht darüber hinaus auch auf GitHub zur Verfügung.

\n

Die QUADRIGA-OER sind nach einem einheitlichen Template gestaltet, werden nach einem standardisierten Verfahren qualitätsgeprüft und mit Metadaten nach dem QUADRIGA-Metadatenschema ausgezeichnet.

\n
QUADRIGA Datenkompetenzzentrum
\n

QUADRIGA ist das Datenkompetenzzentrum der Wissenschaftsregion Berlin-Brandenburg. Für die beiden Anwendungsdomänen Digital Humanities und Verwaltungswissenschaft entstehen unter der Einbindung der Expertise der beiden Disziplinen Informatik und Informationswissenschaft Selbstlernangebote, die als OER in Form von Jupyter Books zur freien Nachnutzung zur Verfügung gestellt werden. Um den Forschungsprozess möglichst realistisch abzubilden, basieren die OER auf Fallstudien, denen wiederum ein eigens für das Projekt entwickeltes Datenkompetenzframework zugrunde liegt. Die Fallstudien nehmen drei für die Anwendungsdomänen repräsentativen Datentypen in den Blick: Bewegtes Bild, Tabelle und Text.

\n

Zu den Zielgruppen von QUADRIGA zählen insbesondere promovierende und promovierte Wissenschaftler*innen der genannten Disziplinen, die den Umgang mit digitalen Daten, Methoden und Werkzeugen erlernen und weiterentwickeln wollen.

\n

QUADRIGA ist eins von 11 Datenkompetenzzentren in Deutschland und wird vom Bundesministerium für Forschung, Technologie und Raumfahrt (BMFTR) und von der Europäischen Union im Rahmen von NextGenerationEU finanziert. Zu den Verbundpartnern zählen:\n

\n

\n\n

Mehr zum Aufbau und zur Umsetzung des Projekts können Sie im Umsetzungskonzept erfahren.

\n\n

Weitere Informationen sowie Publikationen finden Sie auf der Webseite, in der Zenodo-Community und der GitHub-Organisation des Projekts.

\n", "publication_date": "2026-03-11", "keywords": [ "Open Educational Resources", diff --git a/dev-requirements.txt b/dev-requirements.txt index 5c2d287..e4f1ef7 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,9 @@ pyyaml mypy ruff +pre-commit types-PyYAML +types-jsonschema rdflib jupytext jsonschema diff --git a/quadriga/assessment.py b/quadriga/assessment.py index bfb29d1..0b9c762 100644 --- a/quadriga/assessment.py +++ b/quadriga/assessment.py @@ -1,9 +1,10 @@ -from IPython.display import HTML import json import uuid +from IPython.display import HTML + -def create_answer_box(question_id, rows=4): +def create_answer_box(question_id: str, rows: int = 4) -> HTML: """Create an answer box with a submit button.""" return HTML(f"""
@@ -16,7 +17,7 @@ def create_answer_box(question_id, rows=4): class DragDropQuiz: """ A simple drag-and-drop quiz generator for Jupyter Books. - + Usage: quiz = DragDropQuiz() quiz.create_matching_quiz( @@ -26,14 +27,23 @@ class DragDropQuiz: correct_mapping={"Description 1": "Option A", "Description 2": "Option B", "Description 3": "Option C"} ) """ - - def __init__(self): + + def __init__(self) -> None: self.quiz_counter = 0 - - def create_matching_quiz(self, title, descriptions, options, correct_mapping, show_feedback=True, feedback_messages=None): + + def create_matching_quiz( + self, + title: str, + descriptions: list[str], + options: list[str], + correct_mapping: dict, + *, + show_feedback: bool = True, + feedback_messages: dict | None = None, + ) -> HTML: """ Create a drag-and-drop matching quiz. - + Parameters: - title (str): The quiz title/question - descriptions (list): List of items to be matched (static labels) @@ -44,76 +54,92 @@ def create_matching_quiz(self, title, descriptions, options, correct_mapping, sh """ self.quiz_counter += 1 quiz_id = f"drag_drop_quiz_{self.quiz_counter}_{uuid.uuid4().hex[:8]}" - + # Set default feedback messages if none provided if feedback_messages is None: feedback_messages = { "correct": "Perfekt! Alle {total} Zuordnungen sind korrekt!", "incorrect": "Leider sind keine Zuordnungen korrekt. Versuchen Sie es noch einmal!", - "partial": "Teilweise richtig: {correct} von {total} Zuordnungen sind korrekt." + "partial": "Teilweise richtig: {correct} von {total} Zuordnungen sind korrekt.", } - + # Convert correct mapping to use indices for easier JavaScript handling desc_to_idx = {desc: i for i, desc in enumerate(descriptions)} opt_to_idx = {opt: i for i, opt in enumerate(options)} - + correct_pairs = [] for desc, opt in correct_mapping.items(): if desc in desc_to_idx and opt in opt_to_idx: correct_pairs.append([desc_to_idx[desc], opt_to_idx[opt]]) - + html_content = self._generate_html( - quiz_id, title, descriptions, options, correct_pairs, show_feedback, feedback_messages + quiz_id, + title, + descriptions, + options, + correct_pairs, + show_feedback=show_feedback, + feedback_messages=feedback_messages, ) - + return HTML(html_content) - - def _generate_html(self, quiz_id, title, descriptions, options, correct_pairs, show_feedback, feedback_messages): + + def _generate_html( + self, + quiz_id: str, + title: str, + descriptions: list[str], + options: list[str], + correct_pairs: list[list[int]], + *, + show_feedback: bool, + feedback_messages: dict, + ) -> str: """Generate the complete HTML for the drag-and-drop quiz.""" - + # Generate static description labels with drop zones description_zones = "" for i, desc in enumerate(descriptions): - description_zones += f''' + description_zones += f"""
{desc}
Hier ablegen
- ''' - + """ + # Generate draggable options draggable_options = "" for i, option in enumerate(options): - draggable_options += f''' + draggable_options += f"""
{option}
- ''' - - return f''' + """ + + return f"""
{title}
- +
{description_zones}
- +
Ziehen Sie diese zu den passenden Beschreibungen
{draggable_options}
- +
- +
- ''' - - \ No newline at end of file + """ diff --git a/quadriga/metadata/create_rdfxml.py b/quadriga/metadata/create_rdfxml.py index e075256..af9584e 100644 --- a/quadriga/metadata/create_rdfxml.py +++ b/quadriga/metadata/create_rdfxml.py @@ -17,8 +17,8 @@ from pathlib import Path from typing import Any -from rdflib import RDF, Graph, Literal, Namespace, URIRef # type: ignore[import-not-found] -from rdflib.namespace import DCTERMS, SKOS, XSD # type: ignore[import-not-found] +from rdflib import RDF, Graph, Literal, Namespace, URIRef +from rdflib.namespace import DCTERMS, SKOS, XSD from .utils import extract_keywords, get_file_path, get_repo_root, load_yaml_file @@ -153,9 +153,7 @@ def add_person( graph.add((orcid_node, RDF.type, SCHEMA.PropertyValue)) graph.add((orcid_node, SCHEMA.propertyID, Literal("ORCID"))) graph.add((orcid_node, SCHEMA.value, Literal(clean_orcid_id))) - graph.add( - (orcid_node, SCHEMA.url, URIRef(f"https://orcid.org/{clean_orcid_id}")) - ) + graph.add((orcid_node, SCHEMA.url, URIRef(f"https://orcid.org/{clean_orcid_id}"))) graph.add((person_uri, SCHEMA.identifier, orcid_node)) # affiliation -> schema:affiliation (mapped in both author and contributor) @@ -290,9 +288,7 @@ def add_chapter( # learning-objectives -> educationalAlignment with AlignmentObject if chapter_data.get("learning-objectives"): for obj_index, obj_data in enumerate(chapter_data["learning-objectives"]): - obj_uri = add_learning_objective( - graph, obj_data, base_uri, chapter_index, obj_index - ) + obj_uri = add_learning_objective(graph, obj_data, base_uri, chapter_index, obj_index) if obj_uri: graph.add((chapter_uri, SCHEMA.educationalAlignment, obj_uri)) diff --git a/quadriga/metadata/create_zenodo_json.py b/quadriga/metadata/create_zenodo_json.py index dd63bd1..e24eb24 100644 --- a/quadriga/metadata/create_zenodo_json.py +++ b/quadriga/metadata/create_zenodo_json.py @@ -250,15 +250,15 @@ def create_zenodo_json() -> bool | None: return False # description - description = "

" + metadata.get("description") + "

" + description = "

" + metadata.get("description", "TODO TODO TODO") + "

" description_base = f"""

Dieses interaktive Lehrbuch kann als Web-Version verwendet, zur individuellen Anpassung heruntergeladen werden und steht darüber hinaus auch auf GitHub zur Verfügung.

-

Die QUADRIGA-OER sind nach einem einheitlichen Template gestaltet, werden nach einem standardisierten Verfahren qualitätsgeprüft und mit Metadaten nach dem QUADRIGA-Metadatenschema ausgezeichnet.

+

Die QUADRIGA-OER sind nach einem einheitlichen Template gestaltet, werden nach einem standardisierten Verfahren qualitätsgeprüft und mit Metadaten nach dem QUADRIGA-Metadatenschema ausgezeichnet.

QUADRIGA Datenkompetenzzentrum

QUADRIGA ist das Datenkompetenzzentrum der Wissenschaftsregion Berlin-Brandenburg. Für die beiden Anwendungsdomänen Digital Humanities und Verwaltungswissenschaft entstehen unter der Einbindung der Expertise der beiden Disziplinen Informatik und Informationswissenschaft Selbstlernangebote, die als OER in Form von Jupyter Books zur freien Nachnutzung zur Verfügung gestellt werden. Um den Forschungsprozess möglichst realistisch abzubilden, basieren die OER auf Fallstudien, denen wiederum ein eigens für das Projekt entwickeltes Datenkompetenzframework zugrunde liegt. Die Fallstudien nehmen drei für die Anwendungsdomänen repräsentativen Datentypen in den Blick: Bewegtes Bild, Tabelle und Text.

Zu den Zielgruppen von QUADRIGA zählen insbesondere promovierende und promovierte Wissenschaftler*innen der genannten Disziplinen, die den Umgang mit digitalen Daten, Methoden und Werkzeugen erlernen und weiterentwickeln wollen.

-

QUADRIGA ist eins von 11 Datenkompetenzzentren in Deutschland und wird vom Bundesministerium für Forschung, Technologie und Raumfahrt (BMFTR) und von der Europäischen Union im Rahmen von NextGenerationEU finanziert. Zu den Verbundpartnern zählen: +

QUADRIGA ist eins von 11 Datenkompetenzzentren in Deutschland und wird vom Bundesministerium für Forschung, Technologie und Raumfahrt (BMFTR) und von der Europäischen Union im Rahmen von NextGenerationEU finanziert. Zu den Verbundpartnern zählen: