Skip to content

Commit

Permalink
make questions by class from question bank json file
Browse files Browse the repository at this point in the history
  • Loading branch information
floriscalkoen committed Jan 18, 2024
1 parent c3da726 commit 4174bbc
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 109 deletions.
182 changes: 79 additions & 103 deletions cookbook/question_types.ipynb
Original file line number Diff line number Diff line change
@@ -1,12 +1,60 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "da2c1dc2-faa0-4086-b5e3-2483a6b8f762",
"metadata": {},
"source": [
"## Example of how to make questions from a JSON file"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee2ffe05-66ec-43f8-b7e6-2db9302dee83",
"metadata": {
"tags": []
},
"id": "8c947305-86db-4aa3-aa4d-b0d92eaffbbb",
"metadata": {},
"outputs": [],
"source": [
"import pathlib\n",
"\n",
"import panel as pn\n",
"\n",
"import coastal_dynamics as cd\n",
"from coastal_dynamics.io import load_questions\n",
"\n",
"# Activate the Panel widget to make the visualizations.\n",
"pn.extension()\n",
"\n",
"# You can save your questions here. Please follow same naming conventions as the notebooks. When converting a Python dictionary\n",
"# with the questions as they are ATM to a JSON file, watch out for trailing comma's. Your code error will warn you. But if you\n",
"# cannot read the JSON file with the function, it's probably related to that.\n",
"QUESTION_DIR = pathlib.Path.cwd().parent / \"notebooks\" / \"questions\"\n",
"question_fp = QUESTION_DIR / \"01_coastal_classification.json\"\n",
"\n",
"# The coastal dynamics package now contains a small utilty function to load the questions from a JSON file\n",
"questions = load_questions(question_fp)\n",
"\n",
"# The QuestionFactory can handle the four question types.\n",
"q1 = cd.QuestionFactory(\n",
" questions[\"Q1-1\"]\n",
").serve() # Here 1-1 refers to notebook 1 question 1.\n",
"q2 = cd.QuestionFactory(questions[\"Q1-2\"]).serve()\n",
"pn.Column(q1, q2)"
]
},
{
"cell_type": "markdown",
"id": "a98d5110-c1df-4ccd-93a2-69c0766e1b14",
"metadata": {},
"source": [
"## Additional examples for all four question types"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bb7b9bac-90cc-45bc-a150-1c8e665ce58a",
"metadata": {},
"outputs": [],
"source": [
"import pathlib\n",
Expand All @@ -15,29 +63,15 @@
"import geoviews.tile_sources as gvts\n",
"import hvplot.pandas\n",
"import hvplot.xarray\n",
"import panel as pn\n",
"import pooch\n",
"import requests\n",
"\n",
"from coastal_dynamics.geometries import geo_bbox\n",
"from coastal_dynamics.questions.factory import QuestionFactory\n",
"from coastal_dynamics.questions.multiple_choice import MultipleChoiceQuestion\n",
"from coastal_dynamics.questions.multiple_selection import MultipleSelectionQuestion\n",
"from coastal_dynamics.questions.numeric import NumericQuestion\n",
"from coastal_dynamics.questions.text import TextQuestion\n",
"from coastal_dynamics.visualization import DynamicWavePlot\n",
"\n",
"pn.extension()"
]
},
{
"cell_type": "markdown",
"id": "a98d5110-c1df-4ccd-93a2-69c0766e1b14",
"metadata": {},
"source": [
"## Examples for all four question types"
]
},
{
"cell_type": "markdown",
"id": "03cd1328-23c5-4cb4-aedb-5e2ccda3d6ca",
Expand All @@ -53,7 +87,7 @@
"metadata": {},
"outputs": [],
"source": [
"mcq = MultipleChoiceQuestion(\n",
"cd.MultipleChoiceQuestion(\n",
" question_name=\"Q1: Simple Multiple Choice Question\",\n",
" question_text=\"What coastal landform do you typically find in tide-dominated environments?\",\n",
" question_options={\n",
Expand All @@ -63,7 +97,10 @@
" \"d\": \"Mixed sand and gravel beaches\",\n",
" },\n",
" question_answer=\"a\",\n",
" question_feedback={\"correct\": \"Indeed, ...\", \"incorrect\": \"Unfortunately incorrect. Please consder...\"}\n",
" question_feedback={\n",
" \"correct\": \"Indeed, ...\",\n",
" \"incorrect\": \"Unfortunately incorrect. Please consder...\",\n",
" },\n",
").serve()"
]
},
Expand All @@ -82,19 +119,22 @@
"metadata": {},
"outputs": [],
"source": [
"msq = MultipleSelectionQuestion(\n",
"cd.MultipleSelectionQuestion(\n",
" question_name=\"Q1: Simple Multiple Selection Question\",\n",
" question_text=\"Select all morphological systems that are commonly in coastal areas.\",\n",
" question_options={\n",
" \"a\": \"Beaches\",\n",
" \"b\": \"Glaciers\",\n",
" \"c\": \"Estuaries\",\n",
" \"d\": \"Mountains\",\n",
" \"e\": \"Sand\", \n",
" \"f\": \"Mud\", \n",
" \"e\": \"Sand\",\n",
" \"f\": \"Mud\",\n",
" },\n",
" question_answers=[\"a\", \"c\"],\n",
" question_feedback={\"correct\": \"Indeed, ...\", \"incorrect\": \"Unfortunately incorrect. Please consder...\"}\n",
" question_feedback={\n",
" \"correct\": \"Indeed, ...\",\n",
" \"incorrect\": \"Unfortunately incorrect. Please consder...\",\n",
" },\n",
").serve()"
]
},
Expand All @@ -114,13 +154,16 @@
"outputs": [],
"source": [
"kwargs = {\"precision\": 2}\n",
"nq = NumericQuestion(\n",
"cd.NumericQuestion(\n",
" question_name=\"Q3: Simple Numeric Question\",\n",
" question_text=\"What is the PSU of the global ocean?\",\n",
" question_answer=35,\n",
" question_feedback={\"correct\": \"Indeed, ...\", \"incorrect\": \"Unfortunately incorrect. Please consder...\"}, \n",
" question_feedback={\n",
" \"correct\": \"Indeed, ...\",\n",
" \"incorrect\": \"Unfortunately incorrect. Please consder...\",\n",
" },\n",
" **kwargs,\n",
").serve()\n"
").serve()"
]
},
{
Expand All @@ -138,11 +181,14 @@
"metadata": {},
"outputs": [],
"source": [
"TextQuestion(\n",
"cd.TextQuestion(\n",
" question_name=\"Q4: Some simple text question\",\n",
" question_text=\"How do you call the force that generates the tide?\",\n",
" question_answer=\"Gravitational pull\",\n",
" question_feedback={\"correct\": \"Indeed, ...\", \"incorrect\": \"Unfortunately incorrect. Please consder...\"}\n",
" question_feedback={\n",
" \"correct\": \"Indeed, ...\",\n",
" \"incorrect\": \"Unfortunately incorrect. Please consder...\",\n",
" },\n",
").serve().show()"
]
},
Expand Down Expand Up @@ -195,74 +241,6 @@
"pn.Column(wave_plot, base_plot)"
]
},
{
"cell_type": "markdown",
"id": "12f41647-179d-499c-bfd0-b60856307b93",
"metadata": {},
"source": [
"## Make questions from a database (json) that is formatted like below"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "faed7b39",
"metadata": {},
"outputs": [],
"source": [
"## NOTE: Cells below are commented because the factory and json data has to be updated"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb5cbe03-09f6-4e36-98bb-4304be46a526",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"import pooch\n",
"\n",
"template_questions_href = pooch.retrieve(\n",
" \"https://coclico.blob.core.windows.net/coastal-dynamics/questions/template.json\",\n",
" known_hash=\"9ef56da50895d243cc5bdb2184f838a33706195522fbb8992767defd6b8d0b96\",\n",
")\n",
"\n",
"with pathlib.Path(template_questions_href).open(\"r\") as f:\n",
" questions = json.loads(f.read())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "22c3f14c-fad5-44de-9b82-d29e30c3c083",
"metadata": {},
"outputs": [],
"source": [
"questions[\"q1\"]"
]
},
{
"cell_type": "markdown",
"id": "1d30b4bf-1feb-4a87-845b-41291c28b8b5",
"metadata": {},
"source": [
"### This is a factory class that builds the quetions based on the question type"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9bfcb690-ea32-41bd-aa64-96a7d987bee9",
"metadata": {},
"outputs": [],
"source": [
"question_data = questions[\"q1\"]\n",
"factory = QuestionFactory(question_data)\n",
"q1 = factory.create_question_widget().serve() # factory has to be updated because we added a method to add feedback"
]
},
{
"cell_type": "markdown",
"id": "3d26cb47-d55a-40df-a132-0f15af2dc0f6",
Expand All @@ -282,13 +260,11 @@
"\n",
"# Add each question's panel to the main Panel column\n",
"for key, question_data in questions.items():\n",
" question_panel = QuestionFactory(question_data).create_question_widget().serve()\n",
" question_panel = cd.QuestionFactory(question_data).serve()\n",
" all_questions_panel.append(question_panel)\n",
"\n",
"# Create a wave plot and a base plot\n",
"wave_plot = DynamicWavePlot(\n",
" amplitude_range=(1, 3, 0.5), wavelength_range=(5, 20, 0.1)\n",
")\n",
"wave_plot = DynamicWavePlot(amplitude_range=(1, 3, 0.5), wavelength_range=(5, 20, 0.1))\n",
"base_plot = gvts.EsriImagery(width=900, height=500)\n",
"\n",
"# Combine all components into a single dashboard\n",
Expand Down Expand Up @@ -331,9 +307,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "jl-full",
"display_name": "Python [conda env:coastal]",
"language": "python",
"name": "python3"
"name": "conda-env-coastal-py"
},
"language_info": {
"codemirror_mode": {
Expand Down
37 changes: 37 additions & 0 deletions notebooks/questions/01_coastal_classification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"Q1-1": {
"name": "Q1-1",
"type": "multiple_choice",
"question": "At what depth do earthquakes along divergent boundaries generally occur?",
"options": {
"a": "less than 33 km",
"b": "between 33 km and 74 km",
"c": "between 74 km and 140 km",
"d": "more than 140 km "
},
"answer": "a",
"feedback": {
"correct": "Correct, earthquakes at diverging boundaries typically occur at shallower depths",
"incorrect": "Incorrect. Note that at diverging boundaries the tectonic plates move away from each other. Magma wells up to (relatively) shallow depths in order to fill the gap. This may cause earthquakes. Where are these earthquakes likeliest to occur?"
}
},
"Q1-2": {
"name": "Q1-2",
"type": "multiple_selection",
"question": "Where do earthquakes with a depth > 250 km typically occur? Multiple answers may be correct.",
"options": {
"a": "wherever two oceanic plates converge",
"b": "at a boundary between an oceanic and continental plate",
"c": "at island arcs",
"d": "wherever two oceanic plates diverge"
},
"answers": [
"a",
"c"
],
"feedback": {
"correct": "Correct, indeed very deep earthquakes occur mostly when two ocaenic plates converge, or at an island arc.",
"incorrect": "Incorrect. Deep earthquakes occur due to deep processes such as subduction. Due to subduction, island arcs may form (see Figure 2.9 in the book). Where does subduction typically occur?"
}
}
}
6 changes: 3 additions & 3 deletions scripts/python/question_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import panel as pn
import requests

from coastal_dynamics.questions.multiple_choice import MultipleChoiceQuestion
from coastal_dynamics.questions.multiple_selection import MultipleSelectionQuestion
from coastal_dynamics.questions.numeric import NumericQuestion
from coastal_dynamics.multiple_choice import MultipleChoiceQuestion
from coastal_dynamics.multiple_selection import MultipleSelectionQuestion
from coastal_dynamics.numeric import NumericQuestion
from coastal_dynamics.visualization import DynamicWavePlot


Expand Down
2 changes: 1 addition & 1 deletion tests/test_multiple_choice_question.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from coastal_dynamics.questions.multiple_choice import (
from coastal_dynamics.multiple_choice import (
MultipleChoiceQuestion,
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_multiple_selection_question.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from coastal_dynamics.questions.multiple_selection import (
from coastal_dynamics.multiple_selection import (
MultipleSelectionQuestion,
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_numeric_question.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from coastal_dynamics.questions.numeric import NumericQuestion
from coastal_dynamics.numeric import NumericQuestion


def test_numeric_question_correct_answer():
Expand Down

0 comments on commit 4174bbc

Please sign in to comment.