“moved_stuff_from_mude_cookbook_to_jupiter_book_manual”

This commit is contained in:
Isabel Slingerland 2024-02-26 21:19:26 +01:00
parent 4a720f376b
commit 9b04ab332e
17 changed files with 2539 additions and 200 deletions

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -34,7 +34,25 @@ parts:
sections:
- file: features/jupyterlite/configuration
- file: features/jupyterlite/including-jupyterlite
- file: features/custom_toc.md
- file: features/custom_download.md
- file: features/interactive_element
sections:
- file: feutures/h5p_examples
- file: features/theory_questions.md
- file: features/h5p.md
- file: features/live_code.md
sections:
- file: features/widgets.ipynb
- file: features/exercise_checking.ipynb
- caption: Examples
chapters:
- file: examples/overview
- file: examples/overview
- file: examples/interactive_templates.md
sections:
- file: examples/example_gumbel.ipynb
- file: examples/example_quiz_interactive.ipynb
- file: examples/coding_theory_widgets.ipynb
- file: examples/parametric_questions.ipynb

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,259 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"tags": []
},
"source": [
"# Programming assignment\n",
"\n",
"This page shows how you can convert the classical Jupyter Notebook assignment to a jupyter book format with live coding. A widget has been implemented to check the answers, of which the data is included in a separate python file. The page automatically loads and a custom download page has been added\n",
"\n",
"```{custom_download_link} ./example_gumbel_stripped.ipynb\n",
":replace_default: \"True\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"tags": []
},
"source": [
"## Gumbel Distribution Exercise\n",
"\n",
"Imagine you are concerned with the concentration of an airborne contaminant, $X$, measured in ppm. A previous benchmark study estimates that there is a 10% and 1% chance, respectively, of exceeding 4 and 10 ppm, respectively. You have been asked by the regulatory agency to estimate the contaminant concentration with 0.1% probability of being exceeded. Prior studies suggest that a Gumbel distribution can be used to model contaminant concentration, given by the CDF:\n",
"\n",
"$$\n",
"F_X(x) = \\exp{\\Bigg( -\\exp{\\Big(-\\frac{x-\\mu}{\\beta}\\Big)}\\Bigg)}\n",
"$$\n",
"\n",
"Using the cell blocks below as a guide (and also to check your analysis): Task 1) find the parameters of a Gumbel distribution that matches the information provided above, then, Tasks 2-3) use it to estimate the concentration with exceedance probability 0.1%.\n",
"\n",
"To complete this assignment, you can use `numpy`, `matplotlib` and from the `math` library, `log` and `e` (these are imported for you when you inialize the notebook)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"import micropip\n",
"await micropip.install(\"ipywidgets\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"from math import log, e\n",
"import numpy as np\n",
"from example_gumbel import check_example"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Task 0:** fill in the appropriate fitting points:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"auto-execute-page"
]
},
"outputs": [],
"source": [
"x_1 = _\n",
"p_1 = _\n",
"x_2 = _\n",
"p_2 = _"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Task 1:** derive the distribution parameters:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def gumbel_2_points(x_1, p_1, x_2, p_2): \n",
" \"\"\"Compute Gumbel distribution parameters from two points of the CDF.\n",
" Arguments:\n",
" x_1 (float): point one\n",
" p_1 (float): cumulative probability for point 1\n",
" x_2 (float): point two\n",
" p_2 (float): cumulative probability for point 2\n",
" \"\"\"\n",
"\n",
" # YOUR CODE GOES HERE #\n",
" beta = _\n",
" mu = _\n",
" #######################\n",
"\n",
" return mu, beta"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The cells below will print your parameter values and create a plot to help confirm you have the right implementation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"def plot_distribution(mu, beta,\n",
" x_1, p_1, x_2, p_2):\n",
" plt.title(\"Gumbel Distribution, $1-F_X(x)$\")\n",
" plt.xlabel(\"Contaminant Concentration, $X$ [ppm]\")\n",
" plt.ylabel(\"Exceedance Probability [--]\")\n",
" plt.grid(color='black', linestyle='-', linewidth=0.3)\n",
" x_axis = np.arange(0, 20, 0.1)\n",
" plt.plot(x_axis, np.vectorize(gumbel_distribution)(x_axis), linewidth=2)\n",
" plt.plot(x_1, 1 - p_1, 'ro')\n",
" plt.annotate(\"Point 1\", (x_1 + 0.4, 1 - p_1 + 0.02))\n",
" plt.plot(x_2, 1 - p_2, 'ro')\n",
" plt.annotate(\"Point 2\", (x_2 + 0.4, 1 - p_2 + 0.001))\n",
" plt.yscale(\"log\") \n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mu, beta = gumbel_2_points(x_1, p_1, x_2, p_2)\n",
"\n",
"print(f\"Your mu: {mu:0.5f}\\nYour beta: {beta:0.5f}\")\n",
"\n",
"gumbel_distribution = lambda x: 1 - e**(-e**(-(x - mu)/beta))\n",
"\n",
"plot_distribution(mu, beta, x_1, p_1, x_2, p_2)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Task 2:** write a function to solve for the random variable value (it will be tested for you with the Check answer button, along with the distribution parameters)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def find_x_with_probability_p(p): \n",
" \"\"\" Compute point in the gumbel distribution for which the CDF is p\n",
" Use the variables mu and beta defined above!\n",
" Hint: they have been defined globally, so you don't need to \n",
" include them as arguments.\n",
" \"\"\"\n",
" # YOUR CODE GOES HERE #\n",
" x = _\n",
" #######################\n",
"\n",
" return x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Task 3:** use the function `find_x_with_probability_p` to evaluate the random variable value with exceedance probabiltiy of 0.001."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# YOUR CODE GOES HERE #\n",
"x = _\n",
"#######################\n",
"\n",
"print(f\"The value of x with probability of exceedance 0.001 os {x:0.5f}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_example(globals())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View file

@ -0,0 +1,359 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Combining theory with interactive questions and extensive coding assignment\n",
"This page shows an example of how to combine theory, quizzes and code on one page. With headings and boxes, the interactive parts can be indicated (for now only if part of one cell). Automatic execution has been activated and a custom ipynb.file has replaced the download button.\n",
"\n",
"```{custom_download_link} ./example_quiz_interactive_stripped.ipynb\n",
":replace_default: \"True\"\n",
"```\n",
"\n",
"\n",
"## Weighted least-squares estimation\n",
"In ordinary least-squares estimation, we assume that all observations are equally important. In many cases this is not realistic, as observations may be obtained by different measurement systems, or under different circumstances. We want our methodology for least-squares estimation to be able to take this into account.\n",
"\n",
"We achieve this goal by introducing a weight matrix in the minimization problem:\n",
"\n",
"$$\n",
"\\underset{\\mathrm{x}}{\\min} {\\mathrm{(y-Ax)^T W(y-Ax)}}\n",
"$$\n",
"\n",
"In the unweighted least-squares approach, we arrive at the normal equation by pre-multiplying both sides of $\\mathrm{y=Ax}$ with the transpose of the design matrix $\\mathrm{A^T}$:\n",
"\n",
"$$ \n",
"\\mathrm{y=Ax} \\; \\rightarrow \\; \\mathrm{A^T\\; y = A^T\\; A x }\n",
"$$\n",
"\n",
"In the weighted least-squares approach, we now need to add weight matrix $W$ to this pre-multiplication factor, i.e., $ \\mathrm{A^T W}$, to obtain the normal equation:\n",
"\n",
"$$ \n",
"\\mathrm{y=Ax} \\; \\rightarrow \\; \\mathrm{A^T W \\; y = A^TW \\; A x}\n",
"$$\n",
"\n",
"The normal matrix is now defined as $\\mathrm{N=A^T W A}$. From this, assuming that the normal matrix $N$ is invertible (non-singular) we find the weighted least-squares estimate $ \\mathrm{\\hat{x}} $, \n",
"\n",
"$$ \n",
"\\begin{align*}\n",
"\\mathrm{\\hat{x}} &= \\mathrm{(A^T W A)^{-1} A^T W y} \\\\\n",
" &= \\arg \\underset{\\mathrm{x}}{\\min} {\\mathrm{(y-Ax)^T W(y-Ax)}}\n",
"\\end{align*}\n",
"$$\n",
"\n",
"We also find the derived estimate $ \\mathrm{\\hat{y}} $ and $ \\mathrm{\\hat{\\epsilon}} $:\n",
"\n",
"$$\n",
"\\mathrm{\\hat{y} = A \\hat{x} = A (A^T W A )^{-1} A^T W y}\n",
"$$\n",
"\n",
"$$\n",
" \\mathrm{\\hat{\\epsilon} = y - \\hat{y}= y - A \\hat{x} = y-A (A^T W A )^{-1} A^T W y = (I- A(A^T W A )^{-1} A^T W) y}\n",
"$$\n",
"\n",
"### Quiz question\n",
":::{card}\n",
"<iframe src=\"https://tudelft.h5p.com/content/1292046737060674407/embed\" aria-label=\"WLS_1\" width=\"1088\" height=\"637\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\" allow=\"autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *\"></iframe><script src=\"https://tudelft.h5p.com/js/h5p-resizer.js\" charset=\"UTF-8\"></script>\n",
":::\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"### Video\n",
"```{eval-rst}\n",
".. raw:: html\n",
"\n",
" <iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/iJmkkz37EuU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n",
"```\n",
"\n",
"### Discussion on the weight matrix\n",
"The weight matrix $\\mathrm{W}$ expresses the (relative) weights between the observations. It is always a square matrix. The size of the weight matrix depends on the number of observations, $m$. The size of the weight matrix is $m\\times m$. \n",
"\n",
"If it is a unit matrix ($\\mathrm{W=I}$), this implies that all observations have equal weight. Note that in this case the equations are equal to the ordinary least-squares solution. \n",
"\n",
"If it is a diagonal matrix, with different values on the diagonal, this implies that entries with a higher value correspond to the observations which are considered to be of more importance. If the weight matrix has non-zero elements on the off-diagonal positions, this implies that (some) observations are correlated.\n",
"\n",
"### Weighted least-squares estimator: properties\n",
"\n",
"Until now, we have looked at the weighted least-squares solution of a single *realization* of the observations, where generally we assume that it is a realization of the *random* observable vector $Y$, since measurements are affected by random errors. As such it follows the the weighted least-squares *estimator* is given by:\n",
"\n",
"$$\n",
"\\hat{X} = \\mathrm{(A^T W A )^{-1} A^T W} Y\n",
"$$\n",
"\n",
"This estimator has two important properties: it is *linear* and *unbiased*.\n",
"\n",
"The linearity property is due to the fact that $\\hat{X}$ is a linear function of the observables $Y$.\n",
"\n",
"The unbiased property means that the expectation of $\\hat{X}$ is equal to the true (but unknown) $\\mathrm{x}$. This can be shown as follows:\n",
"\n",
"$$\n",
"\\mathbb{E}(\\hat{X}) = \\mathrm{(A^T W A )^{-1} A^T W} \\mathbb{E}(Y) = \\mathrm{(A^T W A )^{-1} A^T W Ax = x}\n",
"$$\n",
"\n",
"This a very desirable property. It applies that if we would repeat the measurements many times to obtain a new estimate, the *average of the estimated* values would be equal to the truy values."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercise\n",
"\n",
":::{card}\n",
"\n",
"You have a time series of 8 measurements and fit a model assuming a linear trend (constant velocity).\n",
"\n",
"Times of observations, observed values and number of observations are given as the variables `t`, `y` and `m`, as well as `numpy` and `matplotlib.pyplot` abbreviated as `np` and `plt`\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"# this will print all float arrays with 3 decimal places\n",
"import numpy as np\n",
"float_formatter = \"{:.2f}\".format\n",
"np.set_printoptions(formatter={'float_kind':float_formatter})\n",
"\n",
"import micropip\n",
"await micropip.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-remove-input-init"
]
},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"# times of observation [months]\n",
"t = np.arange(8)\n",
"\n",
"# observed heights [m]\n",
"y = [1.39, 1.26, 1.48, 4.03, 5.89, 5.14, 6.47, 7.64]\n",
"\n",
"# number of observations\n",
"m = len(t)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{card}\n",
"Fill in the correct $\\mathrm{A}$-matrix.\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"auto-execute-page"
]
},
"outputs": [],
"source": [
"# design matrix\n",
"A = np.column_stack((np.ones(m), t))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_answer(\"A\", np.column_stack((np.ones(m), t)), np.array_equiv)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{card}\n",
"Define the weight matrix for $\\mathrm{W}=I_m$\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"W_1 = 1 #added to have initial input"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Weight matrix for case 1\n",
"W_1 = ?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_answer(\"W_1\",np.eye(m), np.array_equiv)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{card}\n",
"Define the weight matrix with the weight of first 3 observations is five times as large as the rest\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"W_2 = 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Weight matrix for case 2\n",
"W_2 = ?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"# Weight matrix for case 2\n",
"w=5\n",
"W_2_ans = np.eye(m)\n",
"W_2_ans[0,0] = w\n",
"W_2_ans[1,1] = w\n",
"W_2_ans[2,2] = w\n",
"check_answer(\"W_2\",W_2_ans, np.array_equiv)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{card}\n",
"Define the weight matrix with the weight of 4th and 5th observation is five times as large as the rest\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Weight matrix for case 3\n",
"W_3 = ?"
]
}
],
"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.9.18"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}

View file

@ -0,0 +1,16 @@
# Templates for interactive coding / non-coding elements
These pages show examples of how to use interactive coding / non-coding elements in a Jupyter Book.
You can make use of:
- Admonitions
- JupyterQuiz
- H5p
- Grasple-exercises
- Interactive widgets
- Live coding exercise checking with widgets
- Any combination of the above
The following templates are given:
```{tableofcontents}
```

View file

@ -0,0 +1,318 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Parametric question\n",
"\n",
"On this page an example is given for parametric questions, in which an equation is checked on equivalence with the correct answer."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"import sympy as sp\n",
"import numpy as np\n",
"from sympy import pi, latex\n",
"from sympy.printing.mathml import mathml\n",
"\n",
"import operator\n",
"import ipywidgets as widgets\n",
"from IPython.display import display, Latex, display_jpeg, Math, Markdown\n",
"sp.init_printing(use_latex=True) \n",
"\n",
"check_equation = lambda eq1, eq2: sp.simplify(eq1-eq2) == 0\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!',\n",
" 'output_type': 'stream'}]\n",
" else:\n",
" output.outputs = [{'name': 'stdout', 'text': 'Incorrect!',\n",
" 'output_type': 'stream'}]\n",
" button.on_click(_inner_check)\n",
" display(button, output)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exercises on Taylor expansion\n",
"\n",
"This page shows some exercises on calculation Taylor expansion. If you reload this page, you'll get new values.\n",
"\n",
"### Exercise 1\n",
"\n",
"Calculate the taylor series expension of:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true,
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"x, y = sp.symbols('x, y')\n",
"a_1 = sp.Integer(np.random.randint(2,6))\n",
"b_1 = sp.Integer(np.random.randint(-10,10))\n",
"c_1 = sp.Integer(np.random.randint(-5,5))\n",
"eq1_original = a_1 * x**2 + b_1*x\n",
"eq1_correct = sp.series(eq1_original,x,c_1)\n",
"eq1_answer = 0\n",
"display(eq1_original)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"around:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"display(sp.Eq(x,c_1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Fill in your answer and run the cell before clicking 'Check answer'. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"auto-execute-page",
"disable-download-page"
]
},
"outputs": [],
"source": [
"eq1_answer = "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_answer(\"eq1_answer\",eq1_correct, check_equation)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercise 2\n",
"\n",
"Calculate the taylor series expension of:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"a_2 = sp.Integer(np.random.randint(1,7))\n",
"c_2 = sp.Integer(np.random.randint(-5,5))\n",
"eq2_original = a_2*sp.tan(x)\n",
"display(eq2_original)\n",
"eq2_correct = sp.series(eq2_original,x,c_2*sp.pi,3).removeO()\n",
"#display(eq2_correct)\n",
"eq2_answer = 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"around:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"display(sp.Eq(x,c_2*sp.pi))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"discard any $O(x^3)$ terms.\n",
"\n",
"Fill in your answer and run the cell before clicking 'Check answer'. Furthermore, use `pi` for $\\pi$:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eq2_answer = "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_answer(\"eq2_answer\",eq2_correct, check_equation)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercise 3\n",
"\n",
"Calculate the taylor series expension of:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"a_3 = sp.Integer(np.random.randint(1,10))\n",
"c_3 = sp.Integer(np.random.randint(-1,1))\n",
"eq3_original = a_3 / (1 - x)\n",
"display(eq3_original)\n",
"eq3_correct = sp.series(eq3_original,x,c_3,3).removeO()\n",
"#display(eq3_correct)\n",
"eq3_answer = 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"around:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"display(sp.Eq(x,c_3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"discard any $O(x^3)$ terms.\n",
"\n",
"Fill in your answer and run the cell before clicking 'Check answer':"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eq3_answer ="
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"check_answer(\"eq3_answer\",eq3_correct, check_equation)"
]
}
],
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View file

@ -0,0 +1,41 @@
# Page download options
You can control the download option of the book in two ways:
- Disabling downloading using cell tags `disable-download-page`
- Add / replace download link with custom link using `spinhx-download-link-replacer`
## Disabling download
If you add `disable-download-page` as a cell tag to a cell in a python notebook, the download button ({fa}`download`) will disappear from the topright corner. The cell tag can be added to any code cell in the notebook. This function might be handy if your page includes code which you don't want the students to see. Be aware that this also removes the option to download a PDF of the page.
## Add/replace download link
The download link {fa}`download` --> {fa}`file`{guilabel}`.ipynb` can be replaced by using the following code in any markdown / notebook file:
````md
```{custom_download_link} <link_target>
:text: "Custom text"
:replace_default: "True"
```
````
An explanation of the options of this command is given on https://gitlab.tudelft.nl/mude/sphinx-download-link-replacer. This extension can be downloaded by running
`pip install git+https://gitlab.tudelft.nl/mude/sphinx-download-link-replacer`
A potential application of this functionality is when creating a page in which students have to do some coding. Downloading the page allows the student to save their work and work with their local environment. However, the original source file might include code (jupyterbook formatting, widgets, answers) which is not necessary for students. You can make a copy of the notebook file without these elements and replace the {fa}`file`{guilabel}`.ipynb` link to this custom notebook file. Furthermore, you can add any additional data as an additional {fa}`file`{guilabel}`.zip` file.
### Installation instructions
To make use of this functionality, you have to install the `download_link_replace` package by running the following line in your command line:
```
git+https://gitlab.tudelft.nl/mude/sphinx-download-link-replacer
```
Furthermore, you should add the following line to `requirements.txt`
```
download_link_replacer @ git+https://gitlab.tudelft.nl/mude/sphinx-download-link-replacer
```
and to `_config.yml`:
```
sphinx:
extra_extensions:
- download_link_replacer
```

View file

@ -0,0 +1,22 @@
# Exclude parts of book from published book
A new feature is added to enable testing of all interactive features on the web server (i.e., in the draft book) while preventing students from seeing it. Pages in the draft book (`main` branch) can be manually stripped out of the table of contents when a merge request from `main` to `publish` is made using a tag `REMOVE-FROM-PUBLISH`. Pages marked with this feature are still visible in the draft book and books build from source on personal computers. The tag is applied as follows:
```
format: jb-book
root: intro
parts:
- caption: ...
chapters:
- file: ...
...
# START REMOVE-FROM-PUBLISH
- file: files_to_remove
# END REMOVE-FROM-PUBLISH
```
There is no limit to the number of stripped sections, they can be sequential and indentation does not matter. The action is implemented in shell script `build-book.sh` and is executed at run time (see line in script [here](https://gitlab.tudelft.nl/mude/book/-/blob/main/build-book.sh#L13)).
```{note}
The `REMOVE-FROM-PUBLISH` feature was developed to retain testing of all interactive features on the web server and we recommended incorporating this in all books that rely on these features. It avoids problems associated with building the book on various platforms and virtual environments, rather than the actualy webserver where the book will be deployed.
```

View file

@ -0,0 +1,120 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise checking using check-answer button\n",
"\n",
"Using the python-enabled interactivity, exercise checking can be intuitively incorporated using a widgets which checks the value of certain variables with respect to the answer. These examples show different approaches to achieving this goal. \n",
"\n",
"A function has been made to check the value of a variable. As input values it takes the variable name, the expected value (correct answer) and how these values should be compared. You need to add this function to each page, including the imports, and add the `thebe-remove-input-init` tag to the cell.\n",
"```python\n",
"import micropip\n",
"await micropip.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)\n",
"```\n",
"\n",
"To check a float value, you could use `math.isclose` as a function. For checking the equivalence of arrays, you might consider `numpy.array_equiv`\n",
"\n",
"You can choose to include the correct answers in the same notebook. If students download the page and you didn't specify a custom url, they can find the correct answers. You can also place the correct answers in a seperate .py file which you import in the notebook.\n",
"\n",
"## Example"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"import micropip\n",
"await micropip.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",
"auto-execute-page"
]
},
"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
}

View file

@ -0,0 +1,23 @@
# Examples H5p
This page shows some examples of H5p questions.
Some best-practices on the use of H5p:
- To startup your H5p-account, first login to H5p via Brightspace (follow instructions as under [https://www.tudelft.nl/teaching-support/educational-tools/h5p](https://www.tudelft.nl/teaching-support/educational-tools/h5p)). After that, direct login is possible via [tudelft.h5p.com](tudelft.h5p.com)
- Place your H5p-elements in a shared folder in H5p.
- Disable the display options "Toolbar Below Content" and "Display author's name to public (anonymous users) (only relevant when content's status is set to Public )" for each
## Complex fill in the blanks
This can be used to evaluate numerical answers:
<iframe src="https://tudelft.h5p.com/content/1292010272694757307/embed" aria-label="Example MUDE" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
## Dialog cards
This can be used to ask open questions:
<iframe src="https://tudelft.h5p.com/content/1292050206829217497/embed" aria-label="PA1 File Contents" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
## Question set
This can be used to create a set of Multiple Choice, Drag and Drop, Fill in the blanks, True/False questions and Image choice questions:
<iframe src="https://tudelft.h5p.com/content/1292062157562749767/embed" aria-label="quiz_uniform_motion" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
## True/False Question
<iframe src="https://tudelft.h5p.com/content/1292061623388939257/embed" aria-label="quiz_blue_vs_LS" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
# Python-enabled interactivity
Our book has been enable to run Python code live in the browser (thanks Max!). This page contains some installation instructions, and the other sections in this chapter provide some benchmarks which illustrate the functionality that has been added.
## Custom cell tags
With the extended functionality of live code, additional cell tags have been developed to be added to cells in any .ipynb file, next to the [existing tags] of the jupyter book (https://jupyterbook.org/en/stable/content/metadata.html):
- `disable-execution-cell` disables the ability to execute the cell when thebe is activated. This might be useful if you notebook file includes interactivity for only a part of the coding cells
- `disable-execution-page` disable the ability to execute the entire page. This might be useful if you use python code for creating a page, but the code is not part of the actual content of the book.
- `auto-execute-page`, automatically starts the thebe live coding functionality whenever the page is opened. This is particularly useful if you're using widgets on a page. At this moment, this tags doesn't work in combination with `thebe-remove-input-init`
- `thebe-init`, directly starts running this cell as soon as the thebe live coding functionality starts.
- `thebe-remove-input-init`, as `thebe-init` the cell is started directly as soon as the thebe live coding functionality starts. However, the input is not shown to the students (in static and interactive mode). The original `remove-input` tag will not work as it deletes the entire cell, so it can never be executed.
- `keep-output` ...? Max?
## Instructions: local build
To test the fuctionality, you have to run a local server, otherwise the interactivity doens't work. So, you cannot just open the index.html file any more. This can be done with the following steps:
1. build the book by running the shell script `build-book.sh` (type `./build-book.sh true` in the terminal). If you are using Windows you should use the Git Bash terminal. Set this as your default in VS Code, then open it using "New Terminal." If you have not already done so, you will need to allow Git Bash to use your Python libraries by running the command `conda init bash`.Run the shell script from `book/` (not `book/book/`) using `./build-book.sh`. You may notice that `build-book.sh` creates a Python server (`python -m http.server....`) if you include `true` in the command.; this is critical for getting the interactive code pages to work, you cannot just open the index.html file any more.
2. Open the book by going to [http://127.0.0.1:8000/](http://127.0.0.1:8000/) in your browser. You may need to reload the page once the rebuild is complete. You can do this on Chrome by right-clicking somewhere on the page, select "Inspect", open the "Network" tab, then reload with `CTRL+R`. Or try `ctrl`+`F5`
3. Go to any page that is created from a Jupyter notebook
4. In the top right, click "Live Code" in the rocket ship menu item ({fa}`rocket`)
5. Once the message "Python interaction ready!" is displayed, you can run all the cells of the notebook!
If you push to main, you can test the interactivity on the book-draft website as well.

View file

@ -0,0 +1,62 @@
# Combining theory with interactive questions
This page shows you how to combine theory with questions, so there's no coding involved.
```{index} Truss structures
```
## Truss structures
```{contents}
:local:
```
Truss structures are structures assembled of straight elements connected in nodes. These elements partly create triangles, which are of importance for its deformability. Of course, the structures you'll design shouldn't deform, so it's crucial to understand this topic.
### Examples truss structures
Examples of these structures are commonly found in rail bridges like the one below:
```{figure} theory_questions_images/pic0.jpg
:width: 400
```
Furthermore, these structures are commonly found in building as well, both invisible and visible:
```{figure} theory_questions_images/pic1.jpg
:width: 400
```
### Modelling truss structures
Truss structures are modelled as rigid bars (so elements which cannot deform) connected by hinges (so elements can rotate with respect to one each other). In our model, hinges are indicate with a circle, and bars with a line. For example, the structure you've seen in the second example (with two diagonal bars removed) is modelled as follows:
```{figure} theory_questions_images/Truss1.svg
```
Now that you've been introduced to truss structures, answer the following question:
:::{card} Test Yourself
<iframe src="https://tudelft.h5p.com/content/1291910926067816717/embed" aria-label="Modelling truss structures" width="1088" height="200" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
:::
### Mechanisms
A mechanism is a structure which can deform as a whole, while the individual elements don't deform. This deformation doesn't have to be large. An example of a mechanism is a rectangular truss structure, it can deform as shown below:
```{figure} theory_questions_images/rectangle.svg
```
A triangle cannot deform:
```{figure} theory_questions_images/triangle.svg
```
For structures which consists of partly triangles, partly quadrilaterals, it is not directly clear whether the structure can deform. To identify whether the truss structure is a mechanism, you can try to move each node with respect to the nodes with which it is connected:
```{figure} theory_questions_images/gifje.gif
:width: 300px
```
An example of a truss structure of partly triangles, partly quadrilaterals, which is not a mechanism is the following:
```{figure} theory_questions_images/structure3.svg
```
Now that you've been introduced to mechanisms, answer the following questions:
:::{card} Test Yourself
<iframe src="https://tudelft.h5p.com/content/1291910957230324507/embed" aria-label="Truss structures and mechanism" width="1088" height="300 " frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
:::
:::{card} Test Yourself
<iframe src="https://tudelft.h5p.com/content/1291910962551764997/embed" aria-label="Truss structures and mechanims 2" width="1088" height="300" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
:::

192
book/features/widgets.ipynb Normal file
View file

@ -0,0 +1,192 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Widgets\n",
"\n",
"If you publish widgets in a jupyter book they might (depending on your implementation) require an active python kernel for the output to be interactive. Using the [thebe-integration](live_code.md), this is possible. Note: You can circumvent the use of a kernel by using packages which don't need such a kernel, for example the [non-kernel-based widgets using Plotly](interactive_element)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please note:\n",
"- You might want to hide the output before the thebe has been activated.\n",
"- You can hide the code by adding a custom-made tag: `thebe-remove-input-init`.\n",
"- You can automatically start the thebe functionality when you add `auto-execute-page` to a cell. \n",
"\n",
"## Example\n",
"The code below shows an example of the strain energy in a structure and work done by a force for different trial functions. Because of the actual python code, the plot 'refreshes' upon updating a widgets. This can be avoided by updating the current figure instead of plotting a new figure. Remember, first press {fa}`rocket` --> {guilabel}`Live Code` and then wait until all cells are executed:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init",
"auto-execute-page"
]
},
"outputs": [],
"source": [
"import sympy as sp\n",
"F = 10\n",
"EI = 20e3\n",
"L = 3\n",
"\n",
"# Polynomial trial function\n",
"x, C1, C2, C3, C4, F, u0= sp.symbols('x, C1, C2, C3, C4, F, u0')\n",
"w = C1*x**3+C2*x**2+C3*x + C4\n",
"eq1 = sp.Eq(w.subs(x,0),0)\n",
"eq2 = sp.Eq(w.diff(x).subs(x,0),0)\n",
"eq3 = sp.Eq((-w.diff(x,2)*EI).subs(x,L),0)\n",
"eq4 = sp.Eq(w.subs(x,L),u0)\n",
"sol = sp.solve((eq1, eq2,eq3,eq4),(C1,C2,C3,C4))\n",
"w_sol = sp.nsimplify(w.subs(sol))\n",
"w_numpy_polynomial = sp.lambdify((u0,x),w_sol)\n",
"\n",
"M_sol_polynomial = sp.nsimplify(EI * w_sol.diff(x,2))\n",
"\n",
"Ev_polynomial = sp.integrate(sp.nsimplify(M_sol_polynomial**2/(EI*2)),(x,0,3))\n",
"\n",
"Ev_numpy_polynomial = sp.lambdify(u0,Ev_polynomial)\n",
"\n",
"V_polynomial = Ev_polynomial - 10 * u0\n",
"V_numpy_polynomial = sp.lambdify(u0,V_polynomial)\n",
"\n",
"#cosine trial function\n",
"w_sol = u0*sp.sin(x/12*2*sp.pi-sp.pi/2)+u0\n",
"w_numpy_sin = sp.lambdify((u0,x),w_sol)\n",
"\n",
"M_sol_sin = sp.nsimplify(EI * w_sol.diff(x,2))\n",
"\n",
"Ev_sin = sp.integrate(sp.nsimplify(M_sol_sin**2/(EI*2)),(x,0,3))\n",
"\n",
"Ev_numpy_sin = sp.lambdify(u0,Ev_sin)\n",
"\n",
"V_sin = Ev_sin - 10 * u0\n",
"V_numpy_sin = sp.lambdify(u0,V_sin)\n",
"\n",
"#sin trial function\n",
"w_sol = 2*u0*(sp.cosh(x/sp.pi))-2*u0\n",
"w_numpy_cosh = sp.lambdify((u0,x),w_sol)\n",
"\n",
"M_sol_cosh = sp.nsimplify(EI * w_sol.diff(x,2))\n",
"\n",
"Ev_cosh = sp.integrate(sp.nsimplify(M_sol_cosh**2/(EI*2)),(x,0,3))\n",
"\n",
"Ev_numpy_cosh = sp.lambdify(u0,Ev_cosh)\n",
"\n",
"V_cosh = Ev_cosh - 10 * u0\n",
"V_numpy_cosh = sp.lambdify(u0,V_cosh)\n",
"\n",
"import matplotlib.pylab as plt\n",
"import numpy as np\n",
"from ipywidgets import widgets, interact\n",
"\n",
"def func(u,trial_function):\n",
" fig, axs = plt.subplots(2, 2, figsize=(10, 6))\n",
"\n",
" x = np.linspace(0,3,100)\n",
" if trial_function == 'Polynomial':\n",
" w_numpy = w_numpy_polynomial\n",
" Ev_numpy = Ev_numpy_polynomial\n",
" V_numpy = V_numpy_polynomial\n",
" elif trial_function == 'cos':\n",
" w_numpy = w_numpy_sin\n",
" Ev_numpy = Ev_numpy_sin\n",
" V_numpy = V_numpy_sin\n",
" elif trial_function == 'cosh':\n",
" w_numpy = w_numpy_cosh\n",
" Ev_numpy = Ev_numpy_cosh\n",
" V_numpy = V_numpy_cosh\n",
" axs[0,0].plot(x,w_numpy(u,x))\n",
" axs[0,0].set_xlim([-0.2,3.2])\n",
" axs[0,0].set_ylim([-0.003,0.01])\n",
" axs[0,0].invert_yaxis()\n",
" axs[0,0].annotate(text='', xy=(3,w_numpy(u,3)), xytext=(3,0), arrowprops=dict(arrowstyle='fancy'))\n",
" axs[0,0].text(3.1,w_numpy(u,3),'$u_0$')\n",
" axs[0,0].axis('off')\n",
" axs[0,1].axis('off')\n",
" axs[0,1].set_xlim([-0.2,3.2])\n",
" axs[0,1].set_ylim([-0.003,0.01])\n",
" axs[0,1].annotate(text='', xy=(1.5,w_numpy(u,3)), xytext=(1.5,w_numpy(u,3)-0.003), arrowprops=dict(arrowstyle='simple'))\n",
" axs[0,1].invert_yaxis()\n",
" x_axis= ['$E_v$','$A_F$','$E_v - A_F$']\n",
" y_axis = [Ev_numpy(u),w_numpy(u,3)*10,Ev_numpy(u)-w_numpy(u,3)*10]\n",
" axs[1,0].bar(x_axis,y_axis,color=('blue','green','orange'))\n",
" axs[1,0].set_ylim([-0.03,0.1])\n",
" axs[1,0].set_yticklabels([])\n",
" axs[1,0].set_yticks([])\n",
" \n",
" u_range=np.linspace(-0.0015,0.01,100)\n",
" axs[1,1].plot(u_range,Ev_numpy(u_range),label='$E_v$',color='blue')\n",
" axs[1,1].plot(u_range,w_numpy(u_range,3)*10,label='$F_A$',color='green')\n",
" axs[1,1].plot(u_range,V_numpy(u_range),label='$E_v - A_F$',color='orange')\n",
" axs[1,1].legend()\n",
" axs[1,1].plot(u,Ev_numpy(u),'o',color='blue')\n",
" axs[1,1].plot(u,w_numpy(u,3)*10,'o',color='green')\n",
" axs[1,1].plot(u,Ev_numpy(u)-w_numpy(u,3)*10,'o',color='orange')\n",
" axs[1,1].set_ylim([-0.03,0.1])\n",
" axs[1,1].set_xlim([-0.0015,0.01])\n",
" axs[1,1].set_xlabel('$u_0$')\n",
" axs[1,1].set_xticks([])\n",
" axs[1,1].set_xticklabels([])\n",
" axs[1,1].set_yticks([])\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The graph will appear below in interactive mode:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"thebe-remove-input-init"
]
},
"outputs": [],
"source": [
"interact(func, u = widgets.FloatSlider(min=-0.001, max=0.01, value=0, step=0.0002, description=\"Displacement u_0\",readout_format='.4f',style= {'description_width': '180px'},layout = {'width': '400px'}),\n",
" trial_function = widgets.ToggleButtons(options=['Polynomial', 'cos', 'cosh']));"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"celltoolbar": "Tags",
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}