\n",
" WORK IN PROGRESS This notebook is under development, please bear with us...\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Exercises and ssignments - Giving students activities to do\n",
+ "# Exercises and assignments - Giving students activities to do\n",
+ "\n",
+ "## Exercises without programming\n",
+ "\n",
+ "## Exercises with programming\n",
+ "\n",
+ "## Examples \n",
"\n",
"The following examples illustrate different types of exercises and assignments to be used by students either in autonomy or in class with the teaching assistants:\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.
Use case scenario \n",
" This notebook is made to be used in class as a virtual demonstration which is operated by the teacher (the notebook is not meant to be used by students).
\n",
"
Features \n",
" This notebook embeds different types of questions to engage students with the virtual demonstration and uses 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",
" The example chosen is voluntarily simple so that anyone can understand what is illustrated and focus the pedagogical features of the example.
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Falling objects\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Pedagogical goals\n",
+ "## Learning goals\n",
"\n",
- "The goal of this notebook and the associated virtual lab is to illustrate that, if air resistance and friction are negligible, then in a given location all objects fall toward the center of Earth with the same constant acceleration, independent of their mass.\n",
+ "The goal of this notebook and the associated virtual lab is to address a common student misconception that if two objects fall at different speeds it is because of their mass (i.e. an object that is heavier will fall faster than a lighter object). The lab is designed to show that, if air resistance and friction are negligible, then in a given location all objects fall toward the center of Earth with the same constant acceleration, independent of their mass.\n",
"\n",
"## Step 1: Setting the stage\n",
"\n",
"Present the following problem to your students:\n",
"\n",
"
\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",
"
\n",
"\n",
"Ask the following **prediction questions** to your students:\n",
"\n",
"
\n",
" \n",
"1. Which object would reach the ground first: a bowling ball (5 kg) or a tennis ball (0.05 kg)? Write down their answers on a piece of paper.\n",
"2. Why? *Discuss your explanations with your neighbour.*\n",
- "3. Sketch your prediction for the evolution of the *height*, the *velocity* and the *acceleration* of the object as a function of time (draw a graph).\n",
+ "3. Sketch your prediction for the evolution of the *height*, the *velocity* and the *acceleration* of the object as a function of time (draw the graphs).\n",
"\n",
"
\n",
" \n",
"## Step 2: The demo\n",
"\n",
"Execute the cell below to **run the demo**, which shows the movement of several objects with different masses when they are by default in **free fall**. \n",
"You can activate air resistance or not by clicking on the button \"Include air friction\".\n",
"\n",
"We suggest the following series of steps to show different objects on the demo, with **observation questions** to help students see what you want them to see:\n",
"\n",
"1. Select the bowling ball\n",
"\n",
"
\n",
"\n",
"* What is the mass of this object? Note your answer down on a piece of paper.\n",
"* When does the object reach the ground (approximate time in seconds)? Note your answer down on a piece of paper.\n",
"* What would be the equation of the acceleration of the object as a function of time? Note your answer down on a piece of paper.\n",
" \n",
"
\n",
"\n",
"2. Select the air inflated balloon\n",
"\n",
"
\n",
"\n",
"* What is the mass of this object? Note your answer down on a piece of paper.\n",
"* When does the object reach the ground (approximate time in seconds)? Note your answer down on a piece of paper.\n",
"* What would be the equation of the acceleration of the object as a function of time? Note your answer down on a piece of paper.\n",
" \n",
"
\n",
"\n",
"3. Select several objects at the same time (hold the ctrl key while clicking)\n",
"\n",
"
\n",
"\n",
"* What do you observe on the different plots? Note your answer down on a piece of paper.\n",
"* What can you conclude? Note your answer down on a piece of paper.\n",
"\n",
"
\n",
"\n",
"4. Select the air-inflated balloon, then click on the button \"Include air friction\"\n",
"\n",
"
\n",
"\n",
"* When does the object reach the ground (approximate time in seconds)? Note your answer down on a piece of paper.\n",
"* How does the velocity of the object evolves over time? Note your answer down on a piece of paper.\n",
"* How does the acceleration of the object evolves over time? Note your answer down on a piece of paper.\n",
" \n",
"
\n",
"\n",
"5. Select both the bowling ball and the air-inflated balloon (hold the ctrl key while clicking) and make sure the button \"Include air friction\" is activated\n",
"\n",
"
\n",
"\n",
"* What differences do you observe on the velocity of the two objects? Note your answer down on a piece of paper.\n",
"* What differences do you observe on the acceleration of the two objects? Note your answer down on a piece of paper.\n",
" \n",
"
\n",
"\n",
"6. Then ask students this final question:\n",
"\n",
"
\n",
"\n",
"Write down your explanation for what we have just seen.\n",
" \n",
"
\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "b8bf45212bf9458884a099a8ac2910f8",
+ "model_id": "51c63fa72bb046dc8a83b3bd5625cf28",
"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 = True);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\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-demo-work%3F).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 3: The explanation\n",
"\n",
"Provide the explanation (e.g. solving the problem on the board), then ask students: \n",
"\n",
"
\n",
"\n",
"How does your own explanation compare to this one? Note down any questions you might have.\n",
" \n",
"
\n",
"\n",
"Then ask the following **reflection questions**:\n",
"\n",
"
\n",
"\n",
"What are the criteria to decide when we can ignore resistance from the air or not when solving problems?\n",
"\n",
"
\n",
"\n",
" \n",
"\n",
"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": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/jpeg": "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\n",
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo('E43-CfukEgs', 560, 315, start=171)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"---\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": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mInit signature:\u001b[0m\n",
"\u001b[0mFallingObjectsLab\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mobjects\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'Bowling ball'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mass'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'k'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m3.7322120724646743e-05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'color'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'#DC143C'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m'name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'Tennis ball'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mass'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.0567\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'k'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1.0857344210806327e-05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'color'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'#2E8B57'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m'name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'Ping-pong ball'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mass'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.0027\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'k'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m6.7858401317539545e-06\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'color'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'#FF4500'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m'name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'Air-inflated balloon'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mass'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.013\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'k'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.02\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'color'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'#000080'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m9.81\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1.5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mv_0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0.\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m0.05172414\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.10344828\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.15517241\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.20689655\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;36m0.25862069\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.31034483\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.36206897\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.4137931\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m0.46551724\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;36m0.51724138\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.56896552\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.62068966\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.67241379\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.72413793\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;36m0.77586207\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.82758621\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.87931034\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.93103448\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.98275862\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;36m1.03448276\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.0862069\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m1.13793103\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.18965517\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.24137931\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;36m1.29310345\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.34482759\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.39655172\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.44827586\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.5\u001b[0m \u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0maccel_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0maccel_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca48927158\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0mveloc_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mveloc_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca48927268\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0mheight_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mheight_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca418fa400\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0maccel_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0maccel_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca418fa488\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0mveloc_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mveloc_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca418fa510\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
- "\u001b[0;34m\u001b[0m \u001b[0mheight_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mheight_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7fca418fa598\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0maccel_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0maccel_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f6a3180d0\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mveloc_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mveloc_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f6a3181e0\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mheight_time\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mheight_time\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f632ec378\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0maccel_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0maccel_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f632ec400\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mveloc_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mveloc_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f632ec488\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mheight_time_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mheight_time_withair\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7f3f632ec510\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mshow_v_0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mshow_withair\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m This class embeds all the necessary code to create a virtual lab to study the movement of falling objects.\n",
"\u001b[0;31mInit docstring:\u001b[0m\n",
"Initiates and displays the virtual lab on falling objects.\n",
"\n",
":objects: nested dictionnary with the objects to display, which should come with at least the following properties: a name, a mass (in kg) and a color (HEX code)\n",
"\n",
":g: gravitational acceleration constant\n",
":h_0: initial height of the objects\n",
":v_0: initial velocity of the objects\n",
":t: time scale (array of time points at which to compute the equation)\n",
"\n",
":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)\n",
":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)\n",
":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)\n",
"\n",
":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)\n",
":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)\n",
":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)\n",
"\n",
":show_v_0: when True, a slider to change the initial velocity of objects is displayed in the interface\n",
":show_withair: when True, a checkbox allows to plot the equations which include air resistance\n",
"\u001b[0;31mFile:\u001b[0m ~/git/noto-poc-notebooks/TeachingExamples/lib/fallingobjects.py\n",
"\u001b[0;31mType:\u001b[0m type\n",
"\u001b[0;31mSubclasses:\u001b[0m \n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"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": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mheight_time\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mo\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mSource:\u001b[0m \n",
"\u001b[0;32mdef\u001b[0m \u001b[0mheight_time\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mo\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;34m'''\u001b[0m\n",
"\u001b[0;34m Computes the height of the object o as a function of time\u001b[0m\n",
"\u001b[0;34m Implements a constantly accelerated vertical motion (free fall) of equation: h(t) = -1/2.g.t^2 + v_0.t + h_0\u001b[0m\n",
"\u001b[0;34m \u001b[0m\n",
"\u001b[0;34m :o: object considered\u001b[0m\n",
"\u001b[0;34m :g: gravitational acceleration constant\u001b[0m\n",
"\u001b[0;34m :h_0: initial height of the object\u001b[0m\n",
"\u001b[0;34m :v_0: initial velocity of the object\u001b[0m\n",
"\u001b[0;34m :t: time scale (array of time points at which to compute the equation)\u001b[0m\n",
"\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m :returns: array of values for height at each point of the time scale\u001b[0m\n",
"\u001b[0;34m '''\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m0.5\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mg\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mt\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mv_0\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mFile:\u001b[0m ~/git/noto-poc-notebooks/TeachingExamples/lib/fallingobjects.py\n",
"\u001b[0;31mType:\u001b[0m function\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"height_time??"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mheight_time_withair\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mSource:\u001b[0m \n",
"\u001b[0;32mdef\u001b[0m \u001b[0mheight_time_withair\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv_0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;34m'''\u001b[0m\n",
"\u001b[0;34m Computes the height of the object o as a function of time\u001b[0m\n",
"\u001b[0;34m Implements a vertical motion taking into account a linear friction from air\u001b[0m\n",
"\u001b[0;34m \u001b[0m\n",
"\u001b[0;34m :o: object considered -- must have a mass and a friction coefficient k\u001b[0m\n",
"\u001b[0;34m :g: gravitational acceleration constant\u001b[0m\n",
"\u001b[0;34m :h_0: initial height of the object\u001b[0m\n",
"\u001b[0;34m :v_0: initial velocity of the object\u001b[0m\n",
"\u001b[0;34m :t: time scale (array of time points at which to compute the equation)\u001b[0m\n",
"\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m :returns: array of values for height at each point of the time scale\u001b[0m\n",
"\u001b[0;34m '''\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0mcoeff\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mk\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmass\u001b[0m\u001b[0;34m\u001b[0m\n",
"\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mcoeff\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mv_0\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mcoeff\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m \u001b[0mcoeff\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mcoeff\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mh_0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mFile:\u001b[0m ~/git/noto-poc-notebooks/TeachingExamples/lib/fallingobjects.py\n",
"\u001b[0;31mType:\u001b[0m function\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"height_time_withair??"
]
},
{
"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": 4
}
diff --git a/TeachingExamples/FallingObjects-exercise.ipynb b/TeachingExamples/FallingObjects-exercise.ipynb
index 5f093a2..4b89564 100644
--- a/TeachingExamples/FallingObjects-exercise.ipynb
+++ b/TeachingExamples/FallingObjects-exercise.ipynb
@@ -1,337 +1,352 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Use case scenario \n",
" This notebook is made to be used by students as an assignment or exercise, in autonomy (at home or in an exercise session).
\n",
"
Features \n",
" This notebook uses plain text cells to encourage students to take notes when they use a virtual demonstration.
\n",
"
It also embeds different types of questions to engage students with the virtual demonstration and uses 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",
" The example chosen is voluntarily simple so that anyone can understand what is illustrated and focus the pedagogical features of the example.
"
]
},
{
"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",
+ "## 1. 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."
+ "**Question 1.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."
+ "**Question 1.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",
+ "## 2. 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,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"from lib.fallingobjects import *\n",
"FallingObjectsLab();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- " \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).*\n",
+ "\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",
+ "**Question 2.1:** Choose an initial height, e.g. 3 meters, and then observe the movement of 3 different objects as displayed by the lab.\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).*"
+ "\n",
+ "**Question 2.2:** What differences do you observe on the velocity of these objects? And on their acceleration?"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {},
+ "source": [
+ "### Type your answer here."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**Question 2.3:** Look back at your answers to questions 1.1 and 1.2. Do these observations correspond to what you had expected to happen?"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"### Type your answer here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
- "## Synthesis\n",
+ "## 3. Synthesis\n",
"\n",
- "**Question 1:** How does your own explanation compare with the explanation provided below?"
+ "**Question 3.1:** How does your own explanation from question 1.2 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?"
+ "**Question 3.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();"
+ "FallingObjectsLab(show_withair = True);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "**Question 3:** When is it reasonable to ignore the resistance of the air and why? \n",
+ "**Question 3.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": 4
}
diff --git a/TeachingExamples/SuspendedObjects-exercise.ipynb b/TeachingExamples/SuspendedObjects-exercise.ipynb
index f31be2c..6b565b9 100644
--- a/TeachingExamples/SuspendedObjects-exercise.ipynb
+++ b/TeachingExamples/SuspendedObjects-exercise.ipynb
@@ -1,241 +1,336 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Use case scenario \n",
" This notebook is made to be used by students as an assignment or exercise, in autonomy (at home or in an exercise session).
\n",
"
Features \n",
" This notebook embeds auto-corrected quizzes to engage students with the virtual demonstration and uses different types of visualisations to help students understand the phenomena. \n",
" The example chosen is voluntarily simple so that anyone can understand what is illustrated and focus the pedagogical features of the example.
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Suspended objects\n",
"\n",
"We consider a clothesline made of two poles and a cable.\n",
"The cable is fixed on one pole. A pulley on the other pole allows to attach a counterweight to pull the cable taut. \n",
"\n",
"\n",
"\n",
"## Exercise 1\n",
"Execute the cell below to activate the interactive quiz and answer the question."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"from IPython.display import IFrame\n",
"IFrame('https://moodle.epfl.ch/mod/hvp/embed.php?id=1028285', 1024, 500)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exercise 2\n",
"\n",
"The virtual lab below allows you to experiment with different counterweights to see how it affects the position of the object suspended on the clothesline. \n",
"Execute the cell below to launch the virtual lab, then *answer the questions in the quiz below*."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d2cbdd062c4b4984af3688d668e150c7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "VBox(children=(Output(layout=Layout(margin='5px 10px')), HBox(children=(Label(value='Mass of the counterweight…"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"%matplotlib inline\n",
"from lib.suspendedobjects import *\n",
"SuspendedObjectsLab();\n",
"IFrame('https://h5p.org/h5p/embed/584119', 1024, 350)"
]
},
{
"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-lab-work%3F).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exercise 3\n",
"\n",
"1. Give the expression of the **mass of the counterweight $m_{cw}$ as a function of the other parameters of the problem**.\n",
"2. Application: what counterweight allows to suspend wet jeans ($m = 3 kg$) on the cable so that the cable is taut at an angle of $4^\\circ = \\frac{\\pi}{45}$ with the horizon?\n",
"3. Why is it impossible to pull the cable taut completely horizontally?\n",
"\n",
" \n",
"\n",
"## Solution\n",
"\n",
"### Method\n",
"\n",
"Given that the system is in static equilibrium, the sum of external forces exerted on the system will be zero, so using Newton's second law should be easy. The force that the counterweight exerts on the system will involve the mass of the counterweight so we should be able to rewrite Newton's second law to get an expression of the form $m_{cw} = ...$.\n",
"\n",
"### Hypotheses and simplifications\n",
"\n",
"We make the following assumptions and simplifications:\n",
"* the jeans are considered as positioned exactly mid-way between the poles so the tension is equal on both sides of the cable\n",
"* we represent the jeans by the point at which they are suspended\n",
"* the cable is considered as rigid (not bended), with a negligible mass\n",
"* the pulley is considered as perfect, without mass nor friction\n",
"* we consider the static equilibrium obtained after changing the weight, once the system is stabilized\n",
"\n",
"### Resolution\n",
"\n",
"First, let's draw a diagram and represent the different forces involved.\n",
"\n",
"\n",
"The *forces applied on the jeans* are:\n",
"* the weight: $\\vec F_j = m_j \\vec g$ \n",
"* the force exerted by the cable on each side of the jeans: assuming the jeans are suspended at the exact center of the cable, then the tension applied on each of the two sides is is equally distributed $\\vec T$, which combine into a vertical resulting tention $\\vec T_r = 2.\\vec T$\n",
"\n",
"From Newton's second law in a static equilibrium we can write: $\\sum \\vec F_j = \\vec 0$ \n",
"With the forces on the jeans we get: $\\vec F_j + \\vec T_r = 0$ \n",
"Using the fact that the tension is equal on both sides of the jeans we get: $\\vec F_j + 2.\\vec T = 0$\n",
"\n",
"If we project on $x$ and $y$ axes, we get: \n",
"$\\left\\{\\begin{matrix} F_{jx} + 2.T_x = 0 \\\\ F_{jy} + 2.T_y = 0\\end{matrix}\\right. $\n",
"\n",
"Since the weight does not have a component on the x axis, it simplifies into: \n",
"$\\left\\{\\begin{matrix} T_x = 0 \\\\ F_{jy} + 2.T_y = 0\\end{matrix}\\right. $\n",
"\n",
"The component of the weight on the y axis is $F_{jy} = - m_j.g$, which gives us: \n",
"$\\left\\{\\begin{matrix} T_x = 0 \\\\ - m_j.g + 2.T_y = 0\\end{matrix}\\right. $\n",
"\n",
"Using the angle $\\alpha$ we can get the tension $T_y$ expressed as a function of T since $sin(\\alpha) = \\frac{T_y}{T}$, therefore $T_y = T.sin(\\alpha)$\n",
"\n",
"By replacing $T_y$ by this expression in the above equation we get: \n",
"$\\left\\{\\begin{matrix} T_x = 0 \\\\ - m_j.g + 2.T.sin(\\alpha) = 0\\end{matrix}\\right. $\n",
"\n",
"From there we can get $T$, and this is equation number $(1)$: \n",
"$T = \\frac{m_j.g}{2.sin(\\alpha)}$\n",
"\n",
" \n",
"\n",
"We now want to make the mass of the counterweight appear in this expression. \n",
"So we will now look at the forces applied on the *counterweight*.\n",
"\n",
" \n",
"\n",
"The forces applied on the *counterweight* are:\n",
"* the weight: $\\vec F_{cw} = m_{cw} \\vec g$ \n",
"* the force exerted by the line: a simple pulley simply changes the direction of the tension so the tension applied on the counterweight is therefore $\\vec T$\n",
"\n",
"From Newton's second law in a static equilibrium we can write: $\\sum \\vec F_{cw} = \\vec 0$ \n",
"With the forces involved in our problem : $\\vec F_{cw} + \\vec T = \\vec 0$ \n",
"\n",
"All forces being vertical, there is no need to project on $x$ so we get: $- F_{cw} + T = 0$ \n",
"We replace the weight by its detailed expression: $-m_{cw}.g + T = 0$ \n",
"Now we can express $T$ as a function of the other parameters, which is equation number $(2)$: $T = m_{cw}.g$ \n",
"\n",
" \n",
"\n",
"Let's now summarize what we have so far with equations $(1)$ and $(2)$: \n",
"\n",
"$\\left\\{\\begin{matrix}T = \\frac{m_j.g}{2.sin(\\alpha)} \\\\ T = m_{cw}.g\\end{matrix}\\right. $\n",
"\n",
"These two equations combined give us:\n",
"\n",
"$\\frac{m_j.g}{2.sin(\\alpha)} = m_{cw}.g$\n",
"\n",
"This allow us to find the mass of the counterweight as a function of the *mass of the jeans* and of the *angle that the line makes with the horizon*: \n",
"\n",
"$\\boxed{m_{cw} = \\frac{m_j}{2.sin(\\alpha)}}$\n",
"\n",
"\n",
" \n",
"\n",
"### Application\n",
"\n",
"For a pair of wet jeans of $3 kg$ and an angle of $4^\\circ = \\frac{\\pi}{45}$, we need to put a counterweight of:"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "21.503380539305514\n"
+ ]
+ }
+ ],
"source": [
"mcw = 3 / (2 * np.sin(np.pi / 45))\n",
"print(mcw)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can **check that you get a similar result** with the virtual lab above!\n",
"\n",
"\n",
"### Conclusion\n",
"\n",
"For the line to be taut completely horizontal, $\\alpha$ has to be really small i.e. really close to zero. \n",
"This means that $sin(\\alpha)$ will also be close to zero, which means in turn that $m_{cw}$ will be very big.\n",
"Actually, **the more we want the line to be close to the horizon, the bigger $m_{cw}$ we will need!**\n",
"In fact, it is impossible to get the line taut so that it is absolutely straight...\n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"\n",
"---\n",
"\n",
"# How does the virtual lab work?\n",
"\n",
"If you wonder how the virtual lab works: \n",
"* You can have a look at the code of the virtual lab by [opening this python file](lib/suspendedobjects.py).\n",
"* You can see the documentation by executing the cell below:"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\u001b[0;31mInit signature:\u001b[0m\n",
+ "\u001b[0mSuspendedObjectsLab\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mm_object\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mdistance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mheight\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0mx_origin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m \u001b[0my_origin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
+ "\u001b[0;34m\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mDocstring:\u001b[0m This class embeds all the necessary code to create a virtual lab to study the static equilibrium of an object suspended on a clothesline with a counterweight.\n",
+ "\u001b[0;31mInit docstring:\u001b[0m\n",
+ "Initiates and displays the virtual lab on suspended objects.\n",
+ "\n",
+ ":m_object: mass of the suspended object\n",
+ ":distance: horizontal distance between the two poles\n",
+ ":height: height of the poles (same height for both)\n",
+ ":x_origin: x coordinate of the bottom of the left pole (origin of the coordinate system)\n",
+ ":y_origin: y coordinate of the bottom of the left pole (origin of the coordinate system)\n",
+ "\u001b[0;31mFile:\u001b[0m ~/git/noto-poc-notebooks/TeachingExamples/lib/suspendedobjects.py\n",
+ "\u001b[0;31mType:\u001b[0m type\n",
+ "\u001b[0;31mSubclasses:\u001b[0m \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"SuspendedObjectsLab?"
]
}
],
"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": 4
}
diff --git a/TeachingExamples/lib/fallingobjects.py b/TeachingExamples/lib/fallingobjects.py
index e15afc0..dee8056 100644
--- a/TeachingExamples/lib/fallingobjects.py
+++ b/TeachingExamples/lib/fallingobjects.py
@@ -1,345 +1,348 @@
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, show_withair = True):
'''Utility function to print objects nicely'''
return '{!s}:\n mass = {} kg'.format(obj.name, obj.mass)+(' \n friction coeff. = {:.2e} kg/s'.format(obj.k) if show_withair else '')
###--- Virtual lab
class FallingObjectsLab:
"""
This class embeds all the necessary code to create a virtual lab to study the movement of falling objects.
"""
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 = False):
'''
Initiates and displays the virtual lab on falling objects.
:objects: nested dictionnary with the objects to display, which should come with at least the following properties: a name, a mass (in kg) 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.situation_widget = widgets.ToggleButtons(options=[('In vacuum', False), ('In the air', True)], description='Situation:', 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, self.withair))
# 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
diff --git a/Welcome.ipynb b/Welcome.ipynb
index 45e93fb..104b45a 100644
--- a/Welcome.ipynb
+++ b/Welcome.ipynb
@@ -1,79 +1,79 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![EPFL](https://inside.epfl.ch/corp-id/wp-content/uploads/2019/05/EPFL_Logo_Digital_RGB_PROD-300x130.png) ![NOTO](Images/noto_300x130.png)\n",
"\n",
- "# Welcome to ![noto](Images/noto_86x25_inline_transparent.png)'s ![poc](Images/poc_45x25_red.png) notebooks"
+ "# Welcome to ![noto](Images/noto_86x25_inline_transparent.png)'s Proof of Concepts ![poc](Images/poc_45x25_red.png) notebooks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Congratulations!\n",
"\n",
"You have just used `nbgitpuller` to **clone** a git repository (https://c4science.ch/source/noto-poc-notebooks/) and **pull** its content in your jupyter workspace.\n",
"\n",
"The aim of this repository is to give you some practical hints on both the pedagogical and technical aspects of notebook writing.\n",
"\n",
"### Share the link !\n",
"\n",
"Feel free to share the following link and give other people access to this git repository: https://go.epfl.ch/bDS"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Available notebooks\n",
"\n",
"\n",
"| ![pedagogy](https://static1.squarespace.com/static/564f72ade4b0b0384379a293/t/5c7e8aefe79c701d7e5f4763/1551796980913/strategy.png) | Using notebooks for teaching: examples | | ![technical](https://cdn4.iconfinder.com/data/icons/gnome-desktop-icons-png/PNG/64/Gnome-Preferences-System-64.png) | Technical notebooks |\n",
"|:-|:-|--|:-|:-|\n",
"| ![question](https://cdn0.iconfinder.com/data/icons/super-mono-reflection/red/question-balloon_red.png) | Examples of notebooks for [virtual demonstrations](TeachingExamples/01_Demonstrations.ipynb) in class | | ![python](http://www.techteachers.co.za/wp-content/uploads/python-logo64.png) | How to [organize](HowTos/OrganizeCode/OrganizeCode.ipynb) your Python code?|\n",
"| ![question](https://cdn0.iconfinder.com/data/icons/super-mono-reflection/red/question-balloon_red.png) | Examples of notebooks for [exercises and assignments](TeachingExamples/02_Assignments.ipynb) | | ![python](http://www.techteachers.co.za/wp-content/uploads/python-logo64.png) ![multimedia](https://images.sftcdn.net/images/t_app-logo-l,f_auto,dpr_auto/p/974baeec-42f5-405c-8bbc-fec81b7a2bf6/3217395839/focus-picture-gallery-icon.png) | How to embed [external resources](HowTos/EmbedExternalResources/EmbedExternalResources.ipynb) in your notebooks? |\n",
"| | | | ![git](https://www.file-extension.info/images/resource/64/git.png) | How to [share](HowTos/SharingYourNotebooks/SharingYourNotebooks.ipynb) your notebooks wih git? |\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Contact and support\n",
"\n",
"For any question, feel free to contact ![noto](Images/noto_inline_transparent.png) support: [noto-support@groupes.epfl.ch](mailto:noto-support@groupes.epfl.ch)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**End of the 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": 4
}