diff --git a/book/_toc.yml b/book/_toc.yml
index 3ffeda32f4fe00f4913bd42a78e02b994102f096..17ebf32850e43599db649aa095b71f5c8835c0b4 100644
--- a/book/_toc.yml
+++ b/book/_toc.yml
@@ -66,6 +66,7 @@ parts:
       - file: cookbook/benchmarks/benchmark_tags_dont_execute.ipynb
       - file: cookbook/benchmarks/benchmark_load_dont_execute.ipynb
     - file: cookbook/widgets_dont_execute.ipynb
+    - file: cookbook/exercise_checking_dont_execute.ipynb
   - caption: Old Material
     chapters:
     - file: old/blank
diff --git a/book/cookbook/exercise_checking_dont_execute.ipynb b/book/cookbook/exercise_checking_dont_execute.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..45448e3fb6a0789dd00c85b73bd63e866c443c04
--- /dev/null
+++ b/book/cookbook/exercise_checking_dont_execute.ipynb
@@ -0,0 +1,91 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercise checking with interactive elements\n",
+    "\n",
+    "Exercise checking can be intuitively incorporated into Python using tags. These examples show different approaches to achieving this goal. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": [
+     "thebe-remove-input-init"
+    ]
+   },
+   "outputs": [],
+   "source": [
+    "%pip install ipywidgets\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display\n",
+    "import operator\n",
+    "\n",
+    "def check_answer(variable_name, expected, comparison = operator.eq):\n",
+    "    output = widgets.Output()\n",
+    "    button = widgets.Button(description=\"Check answer\")\n",
+    "    def _inner_check(button):\n",
+    "        with output:\n",
+    "            if comparison(globals()[variable_name], expected):\n",
+    "                output.outputs = [{'name': 'stdout', 'text': 'Correct!', 'output_type': 'stream'}]\n",
+    "            else:\n",
+    "                output.outputs = [{'name': 'stdout', 'text': 'Incorrect!', 'output_type': 'stream'}]\n",
+    "    button.on_click(_inner_check)\n",
+    "    display(button, output)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": [
+     "thebe-init"
+    ]
+   },
+   "outputs": [],
+   "source": [
+    "# This example has the user type in the answer as a Python variable, but they need to run the cell to update the answer checked!\n",
+    "pi = 3.14"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": [
+     "thebe-remove-input-init"
+    ]
+   },
+   "outputs": [],
+   "source": [
+    "import math\n",
+    "check_answer(\"pi\", 3.14, math.isclose)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "base",
+   "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.10.6"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}