diff --git a/HowTos/EmbedExternalResources/EmbedExternalResources.ipynb b/HowTos/EmbedExternalResources/EmbedExternalResources.ipynb
index e45d681..79e7c8f 100644
--- a/HowTos/EmbedExternalResources/EmbedExternalResources.ipynb
+++ b/HowTos/EmbedExternalResources/EmbedExternalResources.ipynb
@@ -1,479 +1,468 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Embed external resources in your notebook\n",
"\n",
"**What are external resources?**\n",
"\n",
"External resources are content/resources (videos, images, etc.) that are hosted on services other than Noto.\n",
"\n",
"**What is embeding?**\n",
"\n",
"Embeding is making this external content available from your notebooks, only by providing a reference (a URL, a Youtube video id, data). The external content does not need to be copied into the notebook or your repository.\n",
"\n",
"Note that, **in some cases**, the external content will be stored in the output cell of your notebook."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction\n",
"\n",
"In this section, we will demonstrate how to embed most commom contents in your notebooks using Python ; most of these examples come from [this](http://louistiao.me/posts/demos/ipython-notebook-demo/) page.\n",
"\n",
"## IPython's Rich Display System\n",
"\n",
"To render external content, we will use IPython (the library at the base of Jupyter kernels). In Python, objects can declare their textual representation using the `__repr__` method. IPython expands on this idea and allows objects to declare other, richer representations including:\n",
"\n",
"* HTML\n",
"* JSON\n",
"* PNG\n",
"* JPEG\n",
"* SVG\n",
"* $\\LaTeX$\n",
"\n",
"A single object can declare some or all of these representations; all are handled by IPython's display system. This Notebook shows how you can use this display system to incorporate a broad range of content into your Notebooks.\n",
"\n",
"# About the `display()` function\n",
"The `display()` function is a general purpose tool for displaying different representations of objects. Think of it as a `print()` fonction for these rich representations."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import display"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A few points:\n",
"\n",
"* Calling `display()` on an object will send all possible representations to the Notebook.\n",
"* These representations are stored in the Notebook document (as part of the output cells).\n",
"* In general the Notebook will use the **richest** available representation.\n",
"\n",
"If you want to display a particular representation, there are specific functions for that:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import display_pretty, display_html, display_jpeg, display_png, display_json, display_latex, display_svg, display_pdf"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Examples\n",
"\n",
"Each example is self sufficient; you can just copy and reuse the content of each cell.\n",
"\n",
"## Videos\n",
"\n",
"Embedding a remote video using Python code looks like that:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Video\n",
"Video('http://www.html5videoplayer.net/videos/toystory.mp4')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And this is a YouTube video, embedded via its video ID (`'IPrU6VsLl8c'`)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo('IPrU6VsLl8c', 600, 337)"
]
},
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Of course, videos can also be embedded into Markdown cells using the HTML 5 tag: `` \n",
- "\n",
- "Which gives: \n",
- "\n",
- ""
- ]
- },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Images\n",
"\n",
"JPEG and PNG images are supported."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"Image('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png', width=256, height=192)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also use SVG images - being vector graphics, your browser will extend the image as far as possible."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import SVG\n",
"SVG('https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also set create an IFRAME (with a well define size) and let your browser render the SVG file :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import IFrame\n",
"IFrame('https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg', 200, 200)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course, you can easily include images into Markdown cells, either using the Mardown syntax (see [the reference documentation](https://daringfireball.net/projects/markdown/basics)) or using the HTML syntax: \n",
"``"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Audio files and sound\n",
"\n",
"### Creating sound files"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Audio\n",
"import numpy as np\n",
"\n",
"# Mix two pure sines, 200 Hz and 202 Hz\n",
"framerate = 44100\n",
"t = np.linspace(0,5,framerate*5)\n",
"data = np.sin(2*np.pi*200*t) + np.sin(2*np.pi*202*t)\n",
"\n",
"# Show player - Check the resulting beat\n",
"Audio(data,rate=framerate)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Playing remote Audio files"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Audio\n",
"Audio('https://upload.wikimedia.org/wikipedia/commons/b/bb/Test_ogg_mp3_48kbps.wav')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code\n",
"\n",
"While source code is basically text, it is best displayed using syntax coloring. There are two ways of doing this\n",
"\n",
"### Show the content of a local (or remote) file\n",
"\n",
"Using the `Code` class as shown below works with local and remote files written in many programming languages.. The `Code` class can detect the language (based on the filename extension) and adjust the coloring. In some situation you might have to specify explicitely the language of the contained code.\n",
"\n",
"This method will print in the output cell the **complete** file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Code\n",
"Code('https://raw.githubusercontent.com/jupyterlab/jupyterlab-git/master/jupyterlab_git/__init__.py', language='python')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also display normal text as code, with the proper coloring:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Code\n",
"Code('print(\"hello\")', language='python')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Show selectively Python code (classes, methods, etc.)\n",
"\n",
"You can present to your readers external Python code by selectively presenting only the pieces you want using the `?` and `??` operators.\n",
"\n",
"Let's see the whole `MyLib` class:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from lib.mylib import MyLib\n",
"MyLib??"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's see only the **docstring** for this class:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from lib.mylib import MyLib\n",
"MyLib?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What if you only want to show a single method of `MyLib` class? No problem!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from lib.mylib import MyLib\n",
"MyLib.greet??"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from lib.mylib import MyLib\n",
"MyLib.greet?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note the importance of properly **documenting** your Python code: your documentation texts will pop right into the readers eyeballs when using the `??` and `?` operators."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Markdown, Maths and $\\LaTeX$\n",
"\n",
"### Simple Math text (rendered with MathJax)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Math\n",
"Math(r'F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### $\\LaTeX$ (equations and more)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Latex\n",
"Latex(r\"\"\"\\begin{eqnarray}\n",
"\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\\n",
"\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
"\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
"\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \n",
"\\end{eqnarray}\"\"\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Latex\n",
"Latex(r'To $\\infty$ and beyond!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Markdown"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Markdown\n",
"Markdown('This is markdown text.\\n\\n* Some **more** markdown...\\n* This is a [greek](https://en.wikipedia.org/wiki/Greek) letter: $\\phi$')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## External HTML page (in an IFRAME)\n",
"\n",
"In the next example, an **IFRAME** is created in the output cell, showing you the complete documentation of the **IPython Display** module."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import IFrame\n",
"IFrame('https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html', 1024, 400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## External PDF file (in an IFRAME)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import IFrame\n",
"IFrame('https://rogerdudler.github.io/git-guide/files/git_cheat_sheet.pdf', 1024, 800)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### End of notebook"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
diff --git a/TeachingExamples/01_Demonstrations.ipynb b/TeachingExamples/01_Demonstrations.ipynb
index e3787fa..3449a0f 100644
--- a/TeachingExamples/01_Demonstrations.ipynb
+++ b/TeachingExamples/01_Demonstrations.ipynb
@@ -1,98 +1,134 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Virtual demonstrations - Using digital artefacts to illustrate explanations\n",
"\n",
- "Classroom demonstrations are among students’ favorite elements of introductory science classes and they are well known from teachers to stimulate students’ interest and motivation. \n",
- "Jupyter Notebooks allow you to design very easily **virtual demonstrations** to show students **things that you could not demonstrate in real life**. \n",
+ "Classroom demonstrations, i.e. showing phenomena in class, make great illustrations that stimulate students’ interest and motivation. \n",
+ "Jupyter Notebooks allow you to design very easily *virtual demonstrations* to show students *things that you could not demonstrate in real life*. \n",
"\n",
- "But how to ensure that your demonstrations are **more than just entertainment**?"
+ "But how to make sure that your demonstrations are **more than just entertainment**?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Essential ingredients of virtual demonstrations\n",
- "### Using \"prediction questions\"\n",
"\n",
- "Catherine Crouch and her colleagues at Harvard University (C. Crouch, Fagen, Callan, & Mazur, 2004) were interested in knowing whether the demonstrations traditionally used in introductory science courses were really helping students to learn. More specifically, they wanted to know if there were ways to use classroom demonstrations that would help students better understand than others. \n",
- "So they tested three different ways of using demonstrations in a large introductory physics class (133 students), and assessed students' understanding of the underlying concepts at the end of the semester.\n",
+ "A few simple ingredients can transform your virtual demonstrations into *powerful teaching and learning tools*. Here we summarize briefly some of the ideas from research on the impact of demonstrations on students learning, particularly in Physics Education.\n",
"\n",
- "It turned out that the students who just observed the demonstrations and listened to the explanation from the teacher displayed no greater understanding of the underlying concepts than those who did not see the demonstrations at all. However, *when students were engaged in predicting the outcome of the demonstrations before seing them*, results on the test showed a significantly higher rate of correct explanations compared to both those who just saw the demo and those who didn’t see the demo. This type of result has been reproduced consistently, showing that **having students predict the outcome of a demonstration before doing it can really make your demonstrations more effective** than just entertainment...\n",
+ "
Questions
\n",
"\n",
- "### Including multiple representations\n",
+ "Questionning students can really help students engage actively with your demonstration: \n",
+ "* Catherine Crouch and her colleagues from Harvard University for instance, have shown that **having students predict the outcome of a demonstration before observing it** makes an essential difference in terms of what students remember and understand from a demonstration [(Crouch et al., 2004)](https://aapt.scitation.org/doi/10.1119/1.1707018). This result has been reproduced in a number of other studies and seem to reflect quite well how our brain works according to relatively recent models (see for instance [this video on \"The Brain Seen as a Predictive System\"](https://www.college-de-france.fr/site/en-stanislas-dehaene/course-2011-2012.htm) from Stanislas Dehaene). \n",
+ "* When observing a demonstration, it can be hard for students to focus their attention at the right place at the right time. Asking them questions that drive them to observe specific features of what you are showing can greatly help them see what you want them to see. \n",
+ "* Very often, students have a hard time identifying what they need to remember from a demonstration. Asking them a questions at the end of a demonstration on the important points which have been illustrated is a very effective way to draw their attention to the right elements.\n",
"\n",
+ "In conclusion: ask students questions before (*prediction questions*), during (*observation questions*) and after (*reflection questions*) your demonstrations!\n",
"\n",
- "TODO multiple representations"
+ "Discussions with peers
\n",
+ "\n",
+ "Very frequently, the \"why\" things happen is more important than the \"what\" happens in a demonstration. A key Having students discuss with peers explanations for what happens in the demonstration is another very effective ingredient.\n",
+ "\n",
+ "Multiple visual representations
\n",
+ "\n",
+ "[WORK IN PROGRESS]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Examples of virtual demonstrations for teaching\n",
- "\n",
- "You can show students virtual demonstrations in Jupyter Notebooks in class. As seen above, asking your students prediction questions before showing them the demo will make your virtual demonstrations more effective.\n",
- "Below are examples of simple virtual demonstrations which include prediction questions in different formats.\n",
+ "## Examples of virtual demonstrations for in-class use\n",
+ "You can show students virtual demonstrations in Jupyter Notebooks in class. As seen above, asking your students questions before showing them the demo will make your virtual demonstrations more effective. \n",
+ "The following examples include the above elements in different formats:\n",
"\n",
- "Making the virtual demonstrations available to the students can be a good idea.\n",
- "By transforming them into exercises, which include questions and instructions on what to observe in the demo you will ensure students use them effectively.\n",
- "Below are examples of simple virtual demonstrations turned into homework exercises.\n",
- "\n",
- "\n",
- " \n",
+ "\n",
" \n",
- " | \n",
- " In class | \n",
- " Homework exercise | \n",
+ " | \n",
+ " What is involved? | \n",
+ " Show me an example | \n",
"
\n",
- " \n",
- " \n",
" \n",
- " Suspended objects | \n",
- " This example includes an interactive prediction question in the form of a MCQ that can be asked to students using the notebook or any other technology of your choice (raise of hands, clickers, etc.) | \n",
- " The prediction question makes a nice quiz for students | \n",
+ " \"Low tech\" | \n",
+ " Show the notebook to students, ask them questions where the only thing they have to do is to write their answer on a piece of paper. | \n",
+ " Have a look at the falling objects demo | \n",
"
\n",
" \n",
- " Falling objects | \n",
- " In this example, the prediction question is paper-based, no technology involved other than the notebook! | \n",
- " This example illustrates the idea of a notebook \"to complete\", in which students write their own explanations and observations. \n",
- " This example contains a coding exercise allowing students to get a deeper understanding of how simulations work and develop their computational thinking | \n",
+ " Interactive questions | \n",
+ " Use the notebook to poll students using interactive questions where students vote for the answer of their choice. | \n",
+ " [WORK IN PROGRESS] Have a look at the suspended objects demo | \n",
"
\n",
- " \n",
- "
\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Sharing your demonstration notebooks with students\n",
"\n",
+ "Making the virtual demonstrations available to the students can be a good idea. But how will students know which parameters to change and what to observe? \n",
+ "By including questions and instructions into the notebook with virtual demonstration, you will ensure that students can use them effectively in autonomy. \n",
+ "The following examples are demonstration notebooks extended with questions and instructions for students:\n",
"\n",
+ "\n",
+ " \n",
+ " | \n",
+ " What is involved? | \n",
+ " Show me an example | \n",
+ "
\n",
+ " \n",
+ " \"Low tech\" | \n",
+ " By adding text cells to your notebook, you can transform it into a notebook \"to complete\", in which students write their own explanations and observations. | \n",
+ " Have a look at the falling objects exercise | \n",
+ "
\n",
+ " \n",
+ " Auto-corrected quizz | \n",
+ " Include interactive questions into your notebook to augment your notebook with create auto-corrected quizze. | \n",
+ " [WORK IN PROGRESS] Have a look at the suspended objects exercise | \n",
+ "
\n",
+ " \n",
+ " Computational exercise | \n",
+ " Ask your students to modify or complete the code of your demonstration. | \n",
+ " [WORK IN PROGRESS] Have a look at the falling objects computational exercise | \n",
+ "
\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"## Bibliography\n",
"\n",
"Crouch, C., Fagen, A. P., Callan, J. P., & Mazur, E. (2004). Classroom demonstrations: Learning tools or entertainment? American Journal of Physics, 72(6), 835–838. \n",
"https://aapt.scitation.org/doi/10.1119/1.1707018"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
diff --git a/TeachingExamples/FallingObjects-computational.ipynb b/TeachingExamples/FallingObjects-computational.ipynb
index 237f416..4fc5387 100644
--- a/TeachingExamples/FallingObjects-computational.ipynb
+++ b/TeachingExamples/FallingObjects-computational.ipynb
@@ -1,192 +1,214 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Falling objects - computational exercise\n",
"\n",
- "## 1. Understand the \"Falling objects\" virtual lab\n",
+ "## 1. Get into the \"Falling objects\" virtual lab\n",
"\n",
- "A. First, do the [exercise with the \"Falling objects\" virtual lab](FallingObjects-exercise.ipynb)\n",
- "\n",
- "B. Draw a diagram representing the different elements of the code [available in this python file](lib/suspendedobjects.py). \n"
+ "A. First, do the [exercise with the \"Falling objects\" virtual lab](FallingObjects-exercise.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "07b23378e6f84eca8de8c7490444b8c3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Output(layout=Layout(margin='2px 6px')), HBox(children=(VBox(children=(HBox(children=(Label(val…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"from lib.fallingobjects import *\n",
"FallingObjectsLab();"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "B. Draw a diagram representing the different elements of the code [available in this python file](lib/suspendedobjects.py). "
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Extend the virtual lab\n",
"\n",
"You can extend the virtual lab by redefining the following elements:\n",
"* The list of the objects available in the lab so that you can add properties to these objects\n",
"* The functions representing the equations of motion\n",
" \n",
- "Redefine these elements to implement a quadratic model of air friction in the virtual lab."
+ "**Goal:** redefine the necessary elements to implement **a quadratic model of air friction** and **Archimed's principle** in the virtual lab.\n",
+ "\n",
+ "### 2.1. Rewrite the functions below"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "###--- Functions representing the equations of the movement as functions of time and the problem parameters\n",
+ "def accel_time_withair(obj, g, h_0, v_0, t):\n",
+ " # TODO to replace!! -->\n",
+ " lamb = obj.k / obj.mass\n",
+ " return -g * np.exp(- lamb * t)\n",
+ " # <--\n",
+ "\n",
+ "def veloc_time_withair(obj, g, h_0, v_0, t):\n",
+ " # TODO to replace!! -->\n",
+ " lamb = obj.k / obj.mass\n",
+ " return (v_0 + (g / lamb)) * np.exp(- lamb * t) - (g / lamb)\n",
+ " # <--\n",
+ "\n",
+ "def height_time_withair(obj, g, h_0, v_0, t):\n",
+ " # TODO to replace!! -->\n",
+ " lamb = obj.k / obj.mass\n",
+ " return (1 / lamb) * (v_0 + (g / lamb)) * (1 - np.exp(- lamb * t)) - (g / lamb) * t + h_0\n",
+ " # <--"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2.2. Extend the list of objects with the characteristics that you need in the equations"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"###--- Static list of objects with which we can experiment.\n",
"# Objects come with a number of attributes, of which:\n",
"# - a name and a color : mandatory so that the virtual lab executes\n",
"# - a mass and a friction coefficient : used by the functions implementing the motion equations, can be replaced or renamed \n",
"# as long as the three functions accel_time_withair, veloc_time_withair and height_time_withair are redefined\n",
"objects_with_k = [{\n",
" 'name':'Bowling ball',\n",
" 'mass':5.0,\n",
" 'k': (6*np.pi*0.11) * 1.8*10**-5,\n",
" 'color':'#DC143C'\n",
" },{\n",
" 'name':'Tennis ball',\n",
" 'mass':0.0567,\n",
" 'k': (6*np.pi*0.032) * 1.8*10**-5,\n",
" 'color':'#2E8B57'\n",
" },{\n",
" 'name':'Ping-pong ball',\n",
" 'mass':0.0027,\n",
" 'k': (6*np.pi*0.02) * 1.8*10**-5,\n",
" 'color':'#FF4500'\n",
" },{\n",
" 'name':'Balloon',\n",
" 'mass':0.013,\n",
" 'k': 0.02,#(6*np.pi*0.28) * 1.8*10**-5,\n",
" 'color':'#000080'\n",
"}]\n",
"\n",
"## Utility function to print objects nicely\n",
"def object_string(obj):\n",
- " return '{!s}:\\n mass = {} kg \\n friction coeff. = {:.2e}'.format(obj.name, obj.mass, obj.k)\n",
- "\n",
- "\n",
- "###--- Functions representing the equations of the movement as functions of time and the problem parameters\n",
- "def accel_time_withair(obj, g, h_0, v_0, t):\n",
- " # TODO to replace!! -->\n",
- " lamb = obj.k / obj.mass\n",
- " return -g * np.exp(- lamb * t)\n",
- " # <--\n",
- "\n",
- "def veloc_time_withair(obj, g, h_0, v_0, t):\n",
- " # TODO to replace!! -->\n",
- " lamb = obj.k / obj.mass\n",
- " return (v_0 + (g / lamb)) * np.exp(- lamb * t) - (g / lamb)\n",
- " # <--\n",
- "\n",
- "def height_time_withair(obj, g, h_0, v_0, t):\n",
- " # TODO to replace!! -->\n",
- " lamb = obj.k / obj.mass\n",
- " return (1 / lamb) * (v_0 + (g / lamb)) * (1 - np.exp(- lamb * t)) - (g / lamb) * t + h_0\n",
- " # <--"
+ " return '{!s}:\\n mass = {} kg \\n friction coeff. = {:.2e}'.format(obj.name, obj.mass, obj.k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Test your functions by executing the following cell:"
+ "### 2.3. Test your code \n",
+ "\n",
+ "Execute the following cell:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "30e74080b95643999e5d70fc3957234a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Output(layout=Layout(margin='2px 6px')), HBox(children=(VBox(children=(HBox(children=(Label(val…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"FallingObjectsLab(objects = objects_with_k, \n",
" accel_time = accel_time_withair, veloc_time = veloc_time_withair, height_time = height_time_withair);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References : \n",
"\n",
"frottements linéaires vs. quadratiques : \n",
"\n",
"http://www.physagreg.fr/mecanique/m12/M12-chute-libre-frottements.pdf\n",
"\n",
"https://femto-physique.fr/mecanique/problemes-de-chute.php\n",
"\n",
"equations avec frottements linéaires :\n",
"\n",
"https://fr.wikipedia.org/wiki/Frottement_fluide\n",
"\n",
"equations avec frottements quadratiques :\n",
"\n",
"http://hyperphysics.phy-astr.gsu.edu/hbase/Mechanics/fallq.html\n",
"\n",
"https://studylibfr.com/doc/4875224/chute-libre-avec-frottement---gilles-auriol\n",
"\n",
"https://fr.wikipedia.org/wiki/Chute_avec_r%C3%A9sistance_de_l%27air"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
diff --git a/TeachingExamples/FallingObjects-demo.ipynb b/TeachingExamples/FallingObjects-demo.ipynb
index 377a3af..77714c3 100644
--- a/TeachingExamples/FallingObjects-demo.ipynb
+++ b/TeachingExamples/FallingObjects-demo.ipynb
@@ -1,172 +1,172 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is about demonstrating:\n",
"* using **different types of questions** to engage students with the virtual demonstration\n",
- "* using the type of **visualisations** that students will be asked to use **when solving similar problems**\n",
+ "* using the type of **visualisations** that students will be asked to use **when solving similar problems**, i.e. in this case graphing height, velocity and acceleration as functions of time\n",
"\n",
"The example chosen is voluntarily *simple* so that anyone can understand what is illustrated and focus the pedagogical features of the example.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Falling objects\n",
"\n",
"## In-class scenario\n",
"\n",
"### Problem\n",
"\n",
"We **drop** an object from a given height with **no initial velocity**. Just like an apple would fall from a tree. \n",
"We consider the movement of the object, **ignoring resistance from the air**.\n",
"\n",
"### Questions\n",
"1. Ask the following **prediction questions** to students - make sure they write down their answers on a piece of paper:\n",
" * Which object would reach the ground first: a bowling ball (5 kg) or a tennis ball (0.05 kg)?\n",
" * Why? Describe in words your explanation for this behavior.\n",
" * Sketch your prediction for the *height* of the object as a function of time. Describe in words what this graph means.\n",
" * Sketch your prediction for the *velocity* of the object as a function of time. Describe in words what this graph means.\n",
" * Sketch your prediction for the *acceleartion* of the object as a function of time. Describe in words what this graph means.\n",
"\n",
"\n",
"2. **Run the demo** and ask the following **observation questions** :\n",
" * When does the each object reaches the ground (time in seconds)?\n",
" * What do you observe when we plot multiple objects at the same time?\n",
" * What can you conclude from this experiment?\n",
"\n",
"\n",
"3. Provide the explanation (e.g. solving the problem on the board), and have students compare their explanation with your own explanation. \n",
"Then ask the following **explanation questions**:\n",
" * What happens if we don't ignore the resistance from the air? -- here you can use the virtual lab to show the effect of air resistance\n",
" * What are the criteria to decide when we can ignore resistance from the air or not when solving problems?\n",
"\n",
"\n",
"4. For additional impact, you can show an excerpt of the video below, which demonstrates how a bowling ball and ostrich feathers fall in a vacuum chamber"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Virtual demo"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"from lib.fallingobjects import *\n",
"\n",
"FallingObjectsLab();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*If you wonder how the virtual lab works and would like to see the code, [you can have a look at it at the end of this notebook](#How-does-the-virtual-demo-work%3F).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Video"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import YouTubeVideo\n",
- "YouTubeVideo('E43-CfukEgs', 560, 315)"
+ "YouTubeVideo('E43-CfukEgs', 560, 315, start=171)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"# How does the virtual demo work?\n",
"\n",
"You can have a look at the code of the virtual demo by [opening this python file](lib/fallingobjects.py). \n",
"\n",
"## Use of the virtual demo\n",
"\n",
"Execute the cell below to see the documentation:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"FallingObjectsLab?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Utility computation functions\n",
"\n",
"You can see the code of the functions used to compute the movement equations for the falling objects using the same kind of syntax. \n",
"Below are two examples showing the code of the function computing height without and with air resistance.\n",
"\n",
"These functions can be redefined and given as parameters when initializing the lab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"height_time??"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"height_time_withair??"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
diff --git a/TeachingExamples/FallingObjects-exercise.ipynb b/TeachingExamples/FallingObjects-exercise.ipynb
index be214b2..bda274f 100644
--- a/TeachingExamples/FallingObjects-exercise.ipynb
+++ b/TeachingExamples/FallingObjects-exercise.ipynb
@@ -1,335 +1,350 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is about demonstrating:\n",
"* How to make a **demonstration available to students** in the form of an **exercise including different types of questions**\n",
"* Using notebook cells to encourage students to **take notes** when they use a virtual demonstration\n",
"\n",
"The example chosen is voluntarily *simple* so that anyone can understand what is illustrated and focus the pedagogical features of the example.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Falling objects \n",
"\n",
"## The problem \n",
"We **drop** an object from a given height with **no initial velocity**. Just like an apple would fall from a tree. \n",
"We consider the movement of the object, **ignoring resistance from the air**.\n",
"\n",
" \n",
"\n",
"## Initial questions\n",
"\n",
"Answer the following questions _before_ using the virtual lab.\n",
"\n",
"**Question 1:** Which object would reach the ground first: a bowling ball (5 kg) or a tennis ball (0.05 kg)? Write down your answer in the cell below."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 2:** Why? In the cell below, describe in words your explanation for this behavior."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Tip:* In physics, as in many disciplines, sketching your ideas can really help you figure out problems. \n",
"It might be a good idea to take a piece of paper and sketch what you think the following variables will look like as a function of time: the *height* of the object, the *velocity* of the object and the *acceleration* of the object."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"## Virtual lab\n",
"The virtual demonstration below illustrates the movement of different objects. \n",
"Execute the cell below to launch the virtual demonstration, then *answer the questions below*."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "cb5ed06adcc341d38169b49a6149f51a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "VBox(children=(Output(layout=Layout(margin='2px 6px')), HBox(children=(VBox(children=(HBox(children=(Label(val…"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"%matplotlib inline\n",
"from lib.fallingobjects import *\n",
- "FallingObjectsLab(show_withair=False);"
+ "FallingObjectsLab(show_withair=True);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"**Question 1:** Choose an initial height that will be the same for all the objects you will observe, e.g. 5 meters. \n",
"When does the each object reaches the ground? \n",
"Note down the time in seconds below."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Object 1 reaches the ground at:\n",
"### Object 2 reaches the ground at:\n",
"### Object 3 reaches the ground at:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Tip:* Actually, the interactive figure allows you to plot the movement of several objects simultaneously by maintaining the 'ctrl' key selected while clicking with your mouse on the objects you want to display. \n",
"Try to select several objects to display simultaneously.\n",
"\n",
"**Question 2:** What can you conclude from this experiment? \n",
"*If you wonder how the virtual lab works and would like to see the code, [you can have a look at it at the end of this notebook](#How-does-the-virtual-lab-work%3F).*"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"## Synthesis\n",
"\n",
"**Question 1:** How does your own explanation compare with the explanation provided below?"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Problem analysis\n",
"\n",
"\n",
"We are looking for the time at which the object will reach the ground. Therefore *we are looking for an equation giving us the height of the object as a function of time*.\n",
"\n",
"We know the initial height and velocity of the object, as well as its mass. \n",
"In addition, if we ignore the friction from air, we know that the only force applied on the object is the weight: $\\vec F = m \\vec g$\n",
"\n",
"#### Movement of the object\n",
"Since there is only one force involved, it seems quite straightforward to use Newton's second law: $\\sum \\vec F = m \\vec a$\n",
"\n",
"With the weight the only force on the object, we get: $\\vec F = m \\vec a$ \n",
"Using the expression of the weight it gives us: $m \\vec g = m \\vec a$ \n",
"Therefore the movement of the object is described by $\\vec a = \\vec g$.\n",
"\n",
"To get the equation of acceleration as a function of time, we project onto our coordinate system: $a = -g$, therefore $a(t) = -g$. \n",
"This means that the ball is under **constant acceleration**.\n",
"\n",
"From there we can get the equations for velocity and height by integrating successively: \n",
"$\\left\\{\\begin{matrix} a(t) = -g \\\\ v(t) = -g\\,t + v_0 \\\\ h(t) = -\\frac{1}{2}\\,g\\,t^2 + v_0\\,t + h_0\\end{matrix}\\right. $\n",
"\n",
"The above equations have the following parameters:\n",
"* the initial height $h_0$ from which the object is dropped\n",
"* the initial velocity of the object $v_0$, with $v_0 = 0$ when the object is dropped with no initial velocity\n",
"* and of course the acceleration due to gravity $g$\n",
"\n",
"#### Conclusion\n",
"We see clearly that **the mass $m$ of the object plays no role at all in the equations of the movement**.\n",
"\n",
"**Question 2:** What happens if we don't ignore the resistance of the air?"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Execute the cell below, then click on the button to show the effect of friction from the air. \n",
"Select different objects to see how they are affected depending on their characteristics."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"FallingObjectsLab();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3:** When is it reasonable to ignore the resistance of the air and why? \n",
"List the criteria that you could you to decide if resistance from the air can be ignored or not when solving a problem."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
" \n",
"\n",
"---\n",
"\n",
"## How does that look in real life?\n",
"\n",
"The following video demonstrates how a bowling ball and ostrich feathers fall in a vacuum chamber, thus illustrating how what we have seen so far looks in the real world."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo('E43-CfukEgs', 560, 315)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"---\n",
"## How does the virtual lab work?\n",
"\n",
"You can have a look at the code of the virtual lab by [opening this python file](lib/fallingobjects.py). \n",
"By executing the following three cells, you will see the code of the three functions used to compute the movement equations for the falling object.\n",
"\n",
"#### Code of $a(t) = -g$\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"accel_time??"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Code of $v(t) = -g\\,t + v_0$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"veloc_time??"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Code of $h(t) = -\\frac{1}{2}\\,g\\,t^2 + v_0\\,t + h_0$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"height_time??"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"---\n",
"\n",
"## Other resources on the web\n",
"\n",
"Detailed explanations with examples on falling objects: https://opentextbc.ca/physicstestbook2/chapter/falling-objects/\n",
"\n",
"Impact of air resistance on falling objects (in French): http://www.physagreg.fr/mecanique/m12/M12-chute-libre-frottements.pdf"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
diff --git a/TeachingExamples/SuspendedObjects.ipynb b/TeachingExamples/SuspendedObjects-textbook.ipynb
similarity index 100%
rename from TeachingExamples/SuspendedObjects.ipynb
rename to TeachingExamples/SuspendedObjects-textbook.ipynb
diff --git a/TeachingExamples/lib/fallingobjects.py b/TeachingExamples/lib/fallingobjects.py
index 1e4a1c5..ca5dc73 100644
--- a/TeachingExamples/lib/fallingobjects.py
+++ b/TeachingExamples/lib/fallingobjects.py
@@ -1,345 +1,345 @@
import numpy as np
import pandas
from ipywidgets import interact, interactive, fixed, interact_manual
from ipywidgets import Box, HBox, VBox, Label, Layout
import ipywidgets as widgets
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('svg')
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid') # global style for plotting
###--- Equation functions implementing a model without air resistance (free fall)
def accel_time(o, g, h_0, v_0, t):
'''
Computes the acceleration of the object o as a function of time
Implements a constantly accelerated vertical motion (free fall) of equation: a(t) = -g
:o: object considered
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for acceleration at each point of the time scale
'''
return [-g] * t.size # returning a list of same length as the time interval filled with -g
def veloc_time(o, g, h_0, v_0, t):
'''
Computes the velocity of the object o as a function of time
Implements a constantly accelerated vertical motion (free fall) of equation: v(t) = -g.t + v_0
:o: object considered
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for velocity at each point of the time scale
'''
return -g * t + v_0
def height_time(o, g, h_0, v_0, t):
'''
Computes the height of the object o as a function of time
Implements a constantly accelerated vertical motion (free fall) of equation: h(t) = -1/2.g.t^2 + v_0.t + h_0
:o: object considered
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for height at each point of the time scale
'''
return -0.5 * g * (t **2) + v_0 * t + h_0
###--- Equation functions implementing a model with linear friction from air
def accel_time_withair(obj, g, h_0, v_0, t):
'''
Computes the height of the object o as a function of time
Implements a vertical motion taking into account a linear friction from air
:o: object considered -- must have a mass and a friction coefficient k
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for height at each point of the time scale
'''
coeff = obj.k / obj.mass
return -g * np.exp(- coeff * t)
def veloc_time_withair(obj, g, h_0, v_0, t):
'''
Computes the height of the object o as a function of time
Implements a vertical motion taking into account a linear friction from air
:o: object considered -- must have a mass and a friction coefficient k
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for height at each point of the time scale
'''
coeff = obj.k / obj.mass
return (v_0 + (g / coeff)) * np.exp(- coeff * t) - (g / coeff)
def height_time_withair(obj, g, h_0, v_0, t):
'''
Computes the height of the object o as a function of time
Implements a vertical motion taking into account a linear friction from air
:o: object considered -- must have a mass and a friction coefficient k
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for height at each point of the time scale
'''
coeff = obj.k / obj.mass
return (1 / coeff) * (v_0 + (g / coeff)) * (1 - np.exp(- coeff * t)) - (g / coeff) * t + h_0
###--- Static list of objects with which we can experiment.
# Objects come with a name, a mass (in kg), a friction coefficient and a color for identifying them in the graphical display.
objects = [{
'name':'Bowling ball',
'mass':5.0,
'k': (6*np.pi*0.11) * 1.8*10**-5,
'color':'#DC143C'
},{
'name':'Tennis ball',
'mass':0.0567,
'k': (6*np.pi*0.032) * 1.8*10**-5,
'color':'#2E8B57'
},{
'name':'Ping-pong ball',
'mass':0.0027,
'k': (6*np.pi*0.02) * 1.8*10**-5,
'color':'#FF4500'
},{
'name':'Air-inflated balloon',
'mass':0.013,
'k': 0.02,#(6*np.pi*0.28) * 1.8*10**-5,
'color':'#000080'
}]
def object_string(obj):
'''Utility function to print objects nicely'''
- return '{!s}:\n mass = {} kg \n friction coeff. = {:.2e}'.format(obj.name, obj.mass, obj.k)
+ return '{!s}:\n mass = {} kg \n friction coeff. = {:.2e} kg/s'.format(obj.name, obj.mass, obj.k)
###--- Virtual lab
class FallingObjectsLab:
"""
This class embeds all the necessary code to create a virtual lab to study the movement of objects falling vertically in vacuum.
"""
def __init__(self, objects = objects, g = 9.81, h_0 = 1.5, v_0 = 0, t = np.linspace(0,1.5,30),
accel_time = accel_time, veloc_time = veloc_time, height_time = height_time,
accel_time_withair = accel_time_withair, veloc_time_withair = veloc_time_withair, height_time_withair = height_time_withair,
show_v_0 = False, show_withair = True):
'''
Initiates and displays the virtual lab on falling objects.
:objects: nested dictionnary with the objects to display, which should come with a name, a mass (in kg), a radius (in m) and a color (hex code)
:g: gravitational acceleration constant
:h_0: initial height of the objects
:v_0: initial velocity of the objects
:t: time scale (array of time points at which to compute the equation)
:accel_time: function to compute the acceleration of an object as a function of time -- without air resistance -- a(o, g, h_0, v_0, t)
:veloc_time: function to compute the velocity of an object as a function of time -- without air resistance -- v(o, g, h_0, v_0, t)
:height_time: function to compute the height of an object as a function of time -- without air resistance -- h(o, g, h_0, v_0, t)
:accel_time_withair: function to compute the acceleration of an object as a function of time -- WITH air resistance -- a(o, g, h_0, v_0, t)
:veloc_time_withair: function to compute the velocity of an object as a function of time -- WITH air resistance -- v(o, g, h_0, v_0, t)
:height_time_withair: function to compute the height of an object as a function of time -- WITH air resistance -- h(o, g, h_0, v_0, t)
:show_v_0: when True, a slider to change the initial velocity of objects is displayed in the interface
:show_withair: when True, a checkbox allows to plot the equations which include air resistance
'''
###--- We define the parameters of our problem:
# Create indexed list of objects
self.objects_list = pandas.DataFrame(objects)
self.objects_list.set_index('name', inplace=True) # We index objects by their name to find them easily after
# Initialize list of currently selected objects with first element of the list
self.selected_objs_names = [self.objects_list.index[0],]
# The standard acceleration due to gravity
self.g = g # gravity in m/s2
# The initial conditions of our problem
self.h_0 = h_0 # initial height in m
self.v_0 = v_0 # initial velocity in m/s
# To plot the movement of our objects in time we need to define a time scale.
self.t = t # time interval from 0 to x seconds, with n points in the interval
# Functions to compute movement equations - free fall (no air resistance)
self.accel_time = accel_time
self.veloc_time = veloc_time
self.height_time = height_time
# Functions to compute movement equations - with air resistance (linear friction)
self.withair = False
self.accel_time_withair = accel_time_withair
self.veloc_time_withair = veloc_time_withair
self.height_time_withair = height_time_withair
###--- Then we define the elements of the IHM:
# parameters for sliders
self.h_min = 0
self.h_max = 3
self.v_min = 0
self.v_max = 3
# IHM input elements
input_layout=Layout(margin='2px 6px')
self.h_label = Label('Initial height ($m$):', layout=input_layout)
self.h_widget = widgets.FloatSlider(min=self.h_min,max=self.h_max,value=self.h_0, layout=input_layout)
self.h_input = HBox([self.h_label, self.h_widget])
self.v_label = Label('Initial velocity ($m.s^{-1}$):', layout=input_layout)
self.v_widget = widgets.FloatSlider(min=self.v_min,max=self.v_max,value=self.v_0, layout=input_layout)
self.v_input = HBox([self.v_label, self.v_widget])
self.obj_label = Label('Choice of object(s):', layout=input_layout)
self.obj_widget = widgets.SelectMultiple(
options = self.objects_list.index,
value = self.selected_objs_names,
disabled = False,
layout=input_layout
)
self.obj_input = HBox([self.obj_label, self.obj_widget])
self.air_label = Label('Include air friction:', layout=input_layout)
#self.air_widget = widgets.Checkbox(value=self.withair, layout=input_layout)
self.air_widget = widgets.ToggleButton(value=self.withair, description="ok", layout=input_layout)
self.air_input = HBox([self.air_label, self.air_widget])
# IHM output elements
self.obj_output = widgets.Output(layout=input_layout)
self.graph_output = widgets.Output(layout=input_layout)
# Linking widgets to handlers
self.h_widget.observe(self.h_event_handler, names='value')
self.v_widget.observe(self.v_event_handler, names='value')
self.obj_widget.observe(self.obj_event_handler, names='value')
self.air_widget.observe(self.air_event_handler, names='value')
# Organize layout
opt_inputs = [self.h_input]
if show_v_0: opt_inputs.append(self.v_input)
if show_withair: opt_inputs.append(self.air_input)
self.ihm = VBox([self.graph_output,
HBox([
VBox([self.obj_input, self.obj_output]),
VBox(opt_inputs)
])
])
###--- Finally, we display the whole interface and we update it right away so that it plots the graph with current values
display(self.ihm);
self.update_lab()
# Event handlers
def h_event_handler(self, change):
self.h_0 = change.new
self.update_lab()
def v_event_handler(self, change):
self.v_0 = change.new
self.update_lab()
def obj_event_handler(self, change):
self.selected_objs_names = change.new
self.update_lab()
def air_event_handler(self, change):
self.withair = change.new
self.update_lab()
# Update output function
def update_lab(self):
# Clear outputs
self.graph_output.clear_output(wait=True)
self.obj_output.clear_output(wait=True)
# Create the figure
fig, ax = plt.subplots(1, 3, sharex='col', figsize=(14, 4))
# for each object currently selected
for o_name in self.selected_objs_names:
# Get the selected object
obj = self.objects_list.loc[o_name]
# Recompute equations with parameters set by the user
h_t = self.height_time(obj, self.g, self.h_0, self.v_0, self.t)
v_t = self.veloc_time(obj, self.g, self.h_0, self.v_0, self.t)
a_t = self.accel_time(obj, self.g, self.h_0, self.v_0, self.t)
# Plot equations
ax[0].set_title('Height ($m$)')
ax[0].plot(self.t, h_t, color=obj.color, label=o_name)
ax[0].set_ylim(bottom = 0, top = self.h_max+(self.v_max/2 if self.v_0 > 0 else 0.2))
ax[1].set_title('Velocity ($m.s^{-1}$)')
ax[1].plot(self.t, v_t, color=obj.color, label=o_name)
ax[1].set_ylim(top = self.v_max+1)
ax[2].set_title('Acceleration ($m.s^{-2}$)')
ax[2].plot(self.t, a_t, color=obj.color, label=o_name)
ax[2].set_ylim(top = 0, bottom = - self.g - 1)
# If air resistance is activated, then compute the equations and plot them on top
if self.withair:
h_t_withair = self.height_time_withair(obj, self.g, self.h_0, self.v_0, self.t)
ax[0].plot(self.t, h_t_withair, color=obj.color, linestyle='dashed', label=o_name+" with air friction")
v_t_withair = self.veloc_time_withair(obj, self.g, self.h_0, self.v_0, self.t)
ax[1].plot(self.t, v_t_withair, color=obj.color, linestyle='dashed', label=o_name+" with air friction")
a_t_withair = self.accel_time_withair(obj, self.g, self.h_0, self.v_0, self.t)
ax[2].plot(self.t, a_t_withair, color=obj.color, linestyle='dashed', label=o_name+" with air friction")
# Display characteristics of object selected
with self.obj_output:
print(object_string(obj))
# Add time axis and legend
for a in ax:
a.set_xlabel('Time (s)')
a.legend()
fig.tight_layout()
# Display graph
with self.graph_output:
plt.show();
# EOF