diff --git a/.gitignore b/.gitignore index c4c4ffc..fff487d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.zip +.ipynb_checkpoints +.DS_Store diff --git a/qosf.org/challenge_grading/README.md b/qosf.org/challenge_grading/README.md new file mode 100644 index 0000000..8af30a6 --- /dev/null +++ b/qosf.org/challenge_grading/README.md @@ -0,0 +1,75 @@ +# qosf.org Monthly Challenges + +## Steps for Installing a Grader System for Monthly Challenges + +### Requirements +- **Operating System**: Linux or macOS. On Windows, these bash scripts may not work properly and might need adaptation. +- **Python**: Ensure Python is installed on your system. +- **pip**: Python package installer should be installed. + +### Install +1. Make the shell scripts executable: + ```sh + chmod +x *.sh + ``` +2. Run the install script to install the necessary packages: + ```sh + ./install.sh + ``` + This script installs Jupyter Notebook and nbgrader using pip. + +In this workflow, we will use the directory "challenges" as the course name and the assignment "july" for exemplification. + +### Create Monthly Challenge Directories for Your Notebooks +Create the `[course]/source/[assignment]/` directory. In this case, for the course named "challenges" we will create the assignment for the July Challenge. +```sh +# mkdir -p [course]/source/[assignment]/ +mkdir -p challenges/source/july/ +``` +resulting on the creation `challenges/source/july/` where you shall put your notebooks. + + +### Prepare Release for Distribution +Create the notebooks "compiled" or prepared for distribution to contestants with hidden cells for grading: +```sh +# ./create_release.sh [course] [assignment] +./create_release.sh challenges july +``` + +### Export Assignment ZIP (Optional) +In order to manually distribute the just created notebooks to be fetched by the contestants, run this command to get a zip with the assignment to publish them or send to contestants: +```sh +# ./export_assignment.sh [course] [assignment] [export directory] +./export_assignment.sh challenges july export_directory +``` +The zip will be named after the assignment, in this example case, it will be `july.zip`. + +### Import Contestant Submission +When the contestant submits back a zip with the current assignment's notebooks solved, it should be imported into the directory structure. Run this command: +```sh +# ./import_submission.sh [course] [assignment] [contestants_id] [zipfile] +./import_submission.sh challenges july camargoperez camargoperez_submission.zip +``` + +### Autograde Submission +To grade the contestant's submissions, run this command to perform a run of the notebooks and store the grades in the database: +```sh +# ./autograde.sh [course] [assignment] +./autograde.sh challenges july +``` + +### Create Feedback (Optional) +You can create an HTML report from the graded notebooks for each contestant with this command to provide feedback. The HTML must be copied from `feedback/{contestant_id}/{assignment_id}/{notebook_id}.html`. Templates must have been installed first: +```sh +# ./feedback.sh [course] [assignment] +./feedback.sh challenges july +``` + +### Export the Grades to CSV +To get a report of the contestants grades for this task, export it to CSV from the database: +```sh +# ./export_grades.sh [course] [assignment] [output_csv_file] +./export_grades.sh challenges july grades_july.csv +``` + + diff --git a/qosf.org/challenge_grading/autograde.sh b/qosf.org/challenge_grading/autograde.sh new file mode 100755 index 0000000..8042a10 --- /dev/null +++ b/qosf.org/challenge_grading/autograde.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 course_name assignment_name" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_NAME="$2" + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Check if the course directory exists +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +# Save the current directory +CURRENT_DIR=$(pwd) + +# Change to the course directory +cd "$COURSE_NAME" || { echo "Failed to change directory to '$COURSE_NAME'"; exit 1; } + +# Run nbgrader for the assignment +nbgrader autograde "$ASSIGNMENT_NAME" + +# Return to the previous directory +cd "$CURRENT_DIR" || { echo "Failed to return to directory '$CURRENT_DIR'"; exit 1; } + +echo "nbgrader has been run for assignment '$ASSIGNMENT_NAME' in course '$COURSE_NAME' successfully." + diff --git a/qosf.org/challenge_grading/challenges.csv b/qosf.org/challenge_grading/challenges.csv new file mode 100644 index 0000000..3d9d472 --- /dev/null +++ b/qosf.org/challenge_grading/challenges.csv @@ -0,0 +1,8 @@ +name,due_date +Desafío de Julio,2024-07-31 +Desafío de Agosto,2024-08-31 +Desafío de Septiembre,2024-09-30 +Desafío de Octubre,2024-10-31 +Desafío de Noviembre,2024-11-30 +Desafío de Diciembre,2024-12-31 + diff --git a/qosf.org/challenge_grading/challenges/nbgrader_config.py b/qosf.org/challenge_grading/challenges/nbgrader_config.py new file mode 100644 index 0000000..6e08454 --- /dev/null +++ b/qosf.org/challenge_grading/challenges/nbgrader_config.py @@ -0,0 +1,2 @@ +c = get_config() +c.CourseDirectory.course_id = "challenges" diff --git a/qosf.org/challenge_grading/challenges/release/july/task1.ipynb b/qosf.org/challenge_grading/challenges/release/july/task1.ipynb new file mode 100644 index 0000000..c05f3c1 --- /dev/null +++ b/qosf.org/challenge_grading/challenges/release/july/task1.ipynb @@ -0,0 +1,199 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c291b6e6", + "metadata": {}, + "source": [ + "# Quantum Open Source Foundation Monthly Challenge\n", + "## Quantum Computing with Qiskit\n", + "\n", + "Welcome to the qosf.org monthly challenge! This notebook will guide you through installing Qiskit and performing a simple quantum computing task: applying a controlled-X (CX) gate from qubit 0 to qubit 1 and reading the output." + ] + }, + { + "cell_type": "markdown", + "id": "5911337b", + "metadata": {}, + "source": [ + "### Step 1: Install Qiskit\n", + "First, we need to install Qiskit, a comprehensive open-source quantum computing framework.\n", + "Run the following cell to install Qiskit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4eba720f", + "metadata": {}, + "outputs": [], + "source": [ + "# If you run this notebook on mac, you need to use pip3 instead\n", + "!pip install \"qiskit[visualization]\"\n", + "!pip install matplotlib\n", + "!pip install pylatexenc" + ] + }, + { + "cell_type": "markdown", + "id": "cf7a92b9", + "metadata": {}, + "source": [ + "### Step 2: Import Qiskit and Create a Quantum Circuit\n", + "Next, let's import Qiskit and create a quantum circuit with 2 qubits and 2 classical bits." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "28f9e685", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import QuantumCircuit\n", + "from qiskit.visualization import plot_histogram\n", + "\n", + "# Create a Quantum Circuit with 2 qubits and 2 classical bits\n", + "qc = QuantumCircuit(2, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "3e0d12d6", + "metadata": {}, + "source": [ + "### Step 3: Apply a Controlled-X (CX) Gate\n", + "Now, apply a controlled-X (CX) gate from qubit 0 to qubit 1." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "ca7bbb0f", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "e562add774a207bec89dde823ac2fb75", + "grade": false, + "grade_id": "answer1", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
          ┌─┐   \n",
+       "q_0: ──■──┤M├───\n",
+       "     ┌─┴─┐└╥┘┌─┐\n",
+       "q_1: ┤ X ├─╫─┤M├\n",
+       "     └───┘ ║ └╥┘\n",
+       "c: 2/══════╩══╩═\n",
+       "           0  1 
" + ], + "text/plain": [ + " ┌─┐ \n", + "q_0: ──■──┤M├───\n", + " ┌─┴─┐└╥┘┌─┐\n", + "q_1: ┤ X ├─╫─┤M├\n", + " └───┘ ║ └╥┘\n", + "c: 2/══════╩══╩═\n", + " 0 1 " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Write your code here and don't change the variable or circuit name (qc)\n", + "\n", + "# Apply a controlled-X (CX) gate from qubit 0 to qubit 1 and then measure the quibits\n", + "\n", + "# YOUR CODE HERE\n", + "qc.cx(0, 1)\n", + "qc.measure([0, 1], [0, 1])\n", + "\n", + "# Now let's draw the circuit\n", + "qc.draw(output='text')" + ] + }, + { + "cell_type": "markdown", + "id": "75d856e4", + "metadata": {}, + "source": [ + "### Step 4: Check Your Results\n", + "To verify your implementation, run the following cell to check your circuit" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "952edfa4-7e64-475b-9d2e-dd953894e999", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "20ff9978493354eae5376e4e5fdefaf8", + "grade": true, + "grade_id": "test1", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Done!\n" + ] + } + ], + "source": [ + "\n", + "assert str(qc.data[0][0]) == \"Instruction(name='cx', num_qubits=2, num_clbits=0, params=[])\"\n", + "print(\"Done!\")" + ] + }, + { + "cell_type": "markdown", + "id": "abcf403d", + "metadata": {}, + "source": [ + "Congratulations! You've completed the challenge. Feel free to explore more with Qiskit and quantum computing." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/qosf.org/challenge_grading/challenges/source/july/task1.ipynb b/qosf.org/challenge_grading/challenges/source/july/task1.ipynb new file mode 100644 index 0000000..b6a834f --- /dev/null +++ b/qosf.org/challenge_grading/challenges/source/july/task1.ipynb @@ -0,0 +1,203 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c291b6e6", + "metadata": {}, + "source": [ + "# Quantum Open Source Foundation Monthly Challenge\n", + "## Quantum Computing with Qiskit\n", + "\n", + "Welcome to the qosf.org monthly challenge! This notebook will guide you through installing Qiskit and performing a simple quantum computing task: applying a controlled-X (CX) gate from qubit 0 to qubit 1 and reading the output." + ] + }, + { + "cell_type": "markdown", + "id": "5911337b", + "metadata": {}, + "source": [ + "### Step 1: Install Qiskit\n", + "First, we need to install Qiskit, a comprehensive open-source quantum computing framework.\n", + "Run the following cell to install Qiskit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4eba720f", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# If you run this notebook on mac, you need to use pip3 instead\n", + "!pip install \"qiskit[visualization]\"\n", + "!pip install matplotlib\n", + "!pip install pylatexenc" + ] + }, + { + "cell_type": "markdown", + "id": "cf7a92b9", + "metadata": {}, + "source": [ + "### Step 2: Import Qiskit and Create a Quantum Circuit\n", + "Next, let's import Qiskit and create a quantum circuit with 2 qubits and 2 classical bits." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "28f9e685", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import QuantumCircuit\n", + "from qiskit.visualization import plot_histogram\n", + "\n", + "# Create a Quantum Circuit with 2 qubits and 2 classical bits\n", + "qc = QuantumCircuit(2, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "3e0d12d6", + "metadata": {}, + "source": [ + "### Step 3: Apply a Controlled-X (CX) Gate\n", + "Now, apply a controlled-X (CX) gate from qubit 0 to qubit 1." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ca7bbb0f", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "answer1", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
          ┌─┐   \n",
+       "q_0: ──■──┤M├───\n",
+       "     ┌─┴─┐└╥┘┌─┐\n",
+       "q_1: ┤ X ├─╫─┤M├\n",
+       "     └───┘ ║ └╥┘\n",
+       "c: 2/══════╩══╩═\n",
+       "           0  1 
" + ], + "text/plain": [ + " ┌─┐ \n", + "q_0: ──■──┤M├───\n", + " ┌─┴─┐└╥┘┌─┐\n", + "q_1: ┤ X ├─╫─┤M├\n", + " └───┘ ║ └╥┘\n", + "c: 2/══════╩══╩═\n", + " 0 1 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Write your code here and don't change the variable or circuit name (qc)\n", + "\n", + "# Apply a controlled-X (CX) gate from qubit 0 to qubit 1 and then measure the quibits\n", + "\n", + "### BEGIN SOLUTION\n", + "qc.cx(0, 1)\n", + "qc.measure([0, 1], [0, 1])\n", + "### END SOLUTION\n", + "\n", + "# Now let's draw the circuit\n", + "qc.draw(output='text')" + ] + }, + { + "cell_type": "markdown", + "id": "75d856e4", + "metadata": {}, + "source": [ + "### Step 4: Check Your Results\n", + "To verify your implementation, run the following cell to check your circuit" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "952edfa4-7e64-475b-9d2e-dd953894e999", + "metadata": { + "nbgrader": { + "grade": true, + "grade_id": "test1", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Done!\n" + ] + } + ], + "source": [ + "### BEGIN HIDDEN TESTS\n", + "def check_results():\n", + " cc001 = QuantumCircuit(2, 2)\n", + " cc001.cx(0, 1)\n", + " cc001.measure([0, 1], [0, 1])\n", + " return qc == cc001\n", + "assert check_results()\n", + "### END HIDDEN TESTS\n", + "\n", + "assert str(qc.data[0][0]) == \"Instruction(name='cx', num_qubits=2, num_clbits=0, params=[])\"\n", + "print(\"Done!\")" + ] + }, + { + "cell_type": "markdown", + "id": "abcf403d", + "metadata": {}, + "source": [ + "Congratulations! You've completed the challenge. Feel free to explore more with Qiskit and quantum computing." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/qosf.org/challenge_grading/create_examples.sh b/qosf.org/challenge_grading/create_examples.sh new file mode 100644 index 0000000..e5a2251 --- /dev/null +++ b/qosf.org/challenge_grading/create_examples.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Check if a course name is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 course_name" + exit 1 +fi + +COURSE_NAME="$1" + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Run the nbgrader quickstart command +nbgrader quickstart "$COURSE_NAME" + +echo "Example data for course '$COURSE_NAME' has been created successfully." + diff --git a/qosf.org/challenge_grading/create_release.sh b/qosf.org/challenge_grading/create_release.sh new file mode 100755 index 0000000..b2195b2 --- /dev/null +++ b/qosf.org/challenge_grading/create_release.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Check if a course name is provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 course_name assignment_name" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_NAME="$2" + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Save the current directory +CURRENT_DIR=$(pwd) + +# Change to the course directory +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +cd "$COURSE_NAME" + +# Run the nbgrader generate_assignment command +nbgrader generate_assignment "$ASSIGNMENT_NAME" --force + +# Return to the previous directory +cd "$CURRENT_DIR" + +echo "Assignment '$ASSIGNMENT_NAME' has been generated in course '$COURSE_NAME' successfully." + diff --git a/qosf.org/challenge_grading/export_assignment.sh b/qosf.org/challenge_grading/export_assignment.sh new file mode 100755 index 0000000..88da796 --- /dev/null +++ b/qosf.org/challenge_grading/export_assignment.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Check if assignment name and output directory are provided +if [ "$#" -ne 3 ]; then + echo "Usage: $0 course_name assignment_name output_dir" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_NAME="$2" +OUTPUT_DIR="$3" + +# Check if the output directory exists +if [ ! -d "$OUTPUT_DIR" ]; then + echo "Output directory '$OUTPUT_DIR' does not exist." + exit 1 +fi + +# Check if the course directory exists +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +# Check if the assignment directory exists +ASSIGNMENT_DIR="$COURSE_NAME/release/$ASSIGNMENT_NAME" +if [ ! -d "$ASSIGNMENT_DIR" ]; then + echo "Assignment directory '$ASSIGNMENT_DIR' does not exist." + exit 1 +fi + +# Create the zip file +ZIP_FILE="$OUTPUT_DIR/$ASSIGNMENT_NAME.zip" +zip -j "$ZIP_FILE" "$ASSIGNMENT_DIR"/*.ipynb + +echo "Assignment notebooks have been zipped into '$ZIP_FILE' successfully." + diff --git a/qosf.org/challenge_grading/export_grades.sh b/qosf.org/challenge_grading/export_grades.sh new file mode 100755 index 0000000..1a71c7e --- /dev/null +++ b/qosf.org/challenge_grading/export_grades.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ "$#" -ne 3 ]; then + echo "Usage: $0 course_name assignment_name output_file" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_NAME="$2" +OUTPUT_FILE="$3" + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Check if the course directory exists +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +# Save the current directory +CURRENT_DIR=$(pwd) + +# Change to the course directory +cd "$COURSE_NAME" || { echo "Failed to change directory to '$COURSE_NAME'"; exit 1; } + +# Run nbgrader to export grades +nbgrader export --assignment "$ASSIGNMENT_NAME" + +# Move the grades.csv file to the original directory with the desired name +mv grades.csv "$CURRENT_DIR/$OUTPUT_FILE" + +# Return to the previous directory +cd "$CURRENT_DIR" || { echo "Failed to return to directory '$CURRENT_DIR'"; exit 1; } + +echo "Grades for assignment '$ASSIGNMENT_NAME' in course '$COURSE_NAME' have been exported to '$OUTPUT_FILE' successfully." + diff --git a/qosf.org/challenge_grading/feedback.sh b/qosf.org/challenge_grading/feedback.sh new file mode 100755 index 0000000..09ab585 --- /dev/null +++ b/qosf.org/challenge_grading/feedback.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 course_name assignment_name" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_NAME="$2" + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Check if the course directory exists +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +# Save the current directory +CURRENT_DIR=$(pwd) + +# Change to the course directory +cd "$COURSE_NAME" || { echo "Failed to change directory to '$COURSE_NAME'"; exit 1; } + +# Run nbgrader to generate feedback for the assignment +nbgrader generate_feedback "$ASSIGNMENT_NAME" + +# Return to the previous directory +cd "$CURRENT_DIR" || { echo "Failed to return to directory '$CURRENT_DIR'"; exit 1; } + +echo "Feedback has been generated for assignment '$ASSIGNMENT_NAME' in course '$COURSE_NAME' successfully." + diff --git a/qosf.org/challenge_grading/import_assignments.sh b/qosf.org/challenge_grading/import_assignments.sh new file mode 100755 index 0000000..80529c9 --- /dev/null +++ b/qosf.org/challenge_grading/import_assignments.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Check if a CSV file path is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 path_to_csv_file" + exit 1 +fi + +CSV_FILE="$1" + +# Check if the provided CSV file exists +if [ ! -f "$CSV_FILE" ]; then + echo "CSV file not found: $CSV_FILE" + exit 1 +fi + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Import assignments from the CSV file +nbgrader db assignment import "$CSV_FILE" + +echo "All assignments have been imported successfully." + diff --git a/qosf.org/challenge_grading/import_students.sh b/qosf.org/challenge_grading/import_students.sh new file mode 100755 index 0000000..1ce5432 --- /dev/null +++ b/qosf.org/challenge_grading/import_students.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Check if a CSV file path is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 path_to_csv_file" + exit 1 +fi + +CSV_FILE="$1" + +# Check if the provided CSV file exists +if [ ! -f "$CSV_FILE" ]; then + echo "CSV file not found: $CSV_FILE" + exit 1 +fi + +# Check if nbgrader is installed +if ! command -v nbgrader &> /dev/null; then + echo "nbgrader could not be found, please install it first." + exit 1 +fi + +# Import students from the CSV file +nbgrader db student import "$CSV_FILE" + +echo "All students have been imported successfully." + diff --git a/qosf.org/challenge_grading/import_submission.sh b/qosf.org/challenge_grading/import_submission.sh new file mode 100755 index 0000000..21d1c1e --- /dev/null +++ b/qosf.org/challenge_grading/import_submission.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ "$#" -ne 4 ]; then + echo "Usage: $0 course_name assignment_id student_id zip_file" + exit 1 +fi + +COURSE_NAME="$1" +ASSIGNMENT_ID="$2" +STUDENT_ID="$3" +ZIP_FILE="$4" + +# Check if the provided zip file exists +if [ ! -f "$ZIP_FILE" ]; then + echo "Zip file '$ZIP_FILE' not found." + exit 1 +fi + +# Check if the course directory exists +if [ ! -d "$COURSE_NAME" ]; then + echo "Course directory '$COURSE_NAME' does not exist." + exit 1 +fi + +# Create the submission directory structure +SUBMISSION_DIR="$COURSE_NAME/submitted/$STUDENT_ID/$ASSIGNMENT_ID" +mkdir -p "$SUBMISSION_DIR" + +# Unzip the file to the submission directory +unzip -o "$ZIP_FILE" -d "$SUBMISSION_DIR" + +echo "Submission has been imported to '$SUBMISSION_DIR' successfully." + diff --git a/qosf.org/challenge_grading/install.sh b/qosf.org/challenge_grading/install.sh new file mode 100755 index 0000000..f6a0d65 --- /dev/null +++ b/qosf.org/challenge_grading/install.sh @@ -0,0 +1 @@ +pip install -r requirements.txt diff --git a/qosf.org/challenge_grading/requirements.txt b/qosf.org/challenge_grading/requirements.txt new file mode 100644 index 0000000..eb4e7df --- /dev/null +++ b/qosf.org/challenge_grading/requirements.txt @@ -0,0 +1,2 @@ +jupyter +nbgrader