diff --git a/TeachingExamples/Assignments.ipynb b/TeachingExamples/Assignments.ipynb new file mode 100644 index 0000000..148f3a3 --- /dev/null +++ b/TeachingExamples/Assignments.ipynb @@ -0,0 +1,33 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Assignments - Giving students activities to do\n", + "\n" + ] + } + ], + "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/Demonstrations.ipynb b/TeachingExamples/Demonstrations.ipynb index 999f272..27f59d2 100644 --- a/TeachingExamples/Demonstrations.ipynb +++ b/TeachingExamples/Demonstrations.ipynb @@ -1,96 +1,89 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Demonstrations - Using digital artefacts to improve your explanations\n", "\n", "Sometimes, showing students a phenomenon using a demonstration in class is much simpler than explaining it. For instance, describing only with words the movement of a ball when it is thrown up in the air vertically can be quite lengthy and hard to grasp for students. Whereas throwing up a real ball in the air clearly illustrates what happens. 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", - "\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**?\n", "\n", - "## Using \"prediction questions\"\n", + "## 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", "\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", "\n", - "## Including multiple representations\n", + "### Including multiple representations\n", "\n", "\n", "TODO multiple representations\n", "\n", - "## Teaching with virtual demonstrations\n", + "## 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", "\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", " \n", " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", " \n", " \n", "
In classHomework exercise
Suspended objectsThis example includes a prediction question in the form of a MCQ that can be asked to students using the technology of your choice (raise of hands, clickers, etc.)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.)The prediction question makes a nice quiz for students
Falling objectsIn this example, the prediction question is paper-based, no technology involved!This example illustrates the idea of a notebook \"to complete\", in which students write their own explanations and observations.
\n", + "
In this example, the prediction question is paper-based, no technology involved other than the notebook!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", "\n", "\n", "## 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\n", "\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "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 f029dbb..1b26c62 100644 --- a/TeachingExamples/FallingObjects-demo.ipynb +++ b/TeachingExamples/FallingObjects-demo.ipynb @@ -1,340 +1,180 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook is about demonstrating:\n", "* prediction questions\n", "* observation questions\n", "\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": [ "---\n", "# 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 bowling ball reaches the ground (time in seconds)?\n", " * When does the tennis ball reaches the ground (time in seconds)?\n", " * When does the ostrich feather reaches the ground (time in seconds)?\n", " * What if 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?\n", " * Why can we ignore resistance from the air in this case? \n", " * What are the criteria to decide when we can ignore it 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": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3d258a6c688d41eba51d4e0f1f7f4188", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(Output(layout=Layout(margin='5px 10px')), HBox(children=(VBox(children=(HBox(children=(Label(va…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "from lib.fallingobjects import *\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": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/jpeg": "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\n", - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from IPython.display import YouTubeVideo\n", "YouTubeVideo('E43-CfukEgs', 560, 315)" ] }, { "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": 3, + "execution_count": null, "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[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;36m5\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.125\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.25\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m0.375\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.5\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m0.625\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.75\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m0.875\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[0;36m1.125\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.25\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m1.375\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.5\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m1.625\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.75\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m1.875\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2.\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m2.125\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;36m2.25\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m2.375\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2.5\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m2.625\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2.75\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0;36m2.875\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3.\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[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'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.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'Ostrich feather'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mass'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.005\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'color'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'#483D8B'\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;36m0x7fb3c289e6a8\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;36m0x7fb3c289e7b8\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;36m0x7fb374d7d620\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[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 objects falling vertically in vacuum.\n", - "\u001b[0;31mInit docstring:\u001b[0m\n", - "Initiates and displays the virtual lab on falling objects.\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", - ":objects: nested dictionnary with the objects to display, which should come with a name, a mass (in kg) and a color (hex code)\n", - "\n", - ":accel_time: function to compute the acceleration of the objects as a function of time -- a(g, h_0, v_0, m, t)\n", - ":veloc_time: function to compute the velocity of the objects as a function of time -- v(g, h_0, v_0, m, t)\n", - ":height_time: function to compute the height of the objects as a function of time -- h(g, h_0, v_0, m, t)\n", - "\n", - ":show_v_0: when True, a slider to change the initial velocity of objects is displayed in the interface\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" - } - ], + "outputs": [], "source": [ "FallingObjectsLab?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Utility computation functions\n", "\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 objects. \n", "These functions can be redefined and given as parameters when initializing the lab." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0maccel_time\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[0mm\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[0maccel_time\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[0mm\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 acceleration of the object as a function of time\u001b[0m\n", - "\u001b[0;34m a(t) = -g\u001b[0m\n", - "\u001b[0;34m \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 :m: mass 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 acceleration 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;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[0msize\u001b[0m \u001b[0;31m# returning a list of same length as the time interval filled with -g\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" - } - ], + "outputs": [], "source": [ "accel_time??" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mveloc_time\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[0mm\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[0mveloc_time\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[0mm\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 velocity of the object as a function of time \u001b[0m\n", - "\u001b[0;34m v(t) = -g.t + v_0\u001b[0m\n", - "\u001b[0;34m \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 :m: mass 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 velocity 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[0mg\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mv_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" - } - ], + "outputs": [], "source": [ "veloc_time??" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mheight_time\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[0mm\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[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[0mm\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 as a function of time\u001b[0m\n", - "\u001b[0;34m h(t) = -1/2.g.t^2 + v_0.t + h_0\u001b[0m\n", - "\u001b[0;34m \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 :m: mass 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" - } - ], + "outputs": [], "source": [ "height_time??" ] } ], "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-demo.ipynb b/TeachingExamples/SuspendedObjects-demo.ipynb index db6738f..6da8587 100644 --- a/TeachingExamples/SuspendedObjects-demo.ipynb +++ b/TeachingExamples/SuspendedObjects-demo.ipynb @@ -1,257 +1,145 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Suspended objects\n", "\n", "## In-class scenario\n", "\n", "### Problem\n", "\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", "### Questions\n", "\n", "1. Ask the following **prediction question** to students:\n", - "\n", + " * Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram: 1,5 kg, 3 kg, 6 kg, 20 kg, 50 kg or more\n", + " * Why? Describe in words your explanation for this behavior.\n", + " \n", "#### TODO: here, replace by interactive polling question!!!\n", "\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram: \n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "24c2cb9ccb654da8870acd09128b0b7f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Dropdown(description='w', options=('1,5 kg', '3 kg', '6 kg', '20 kg', '50 kg or more'), …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from ipywidgets import interact\n", "print(\"Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram: \")\n", "f = lambda w:str(w)\n", "interact(f, w=['1,5 kg', '3 kg', '6 kg', '20 kg', '50 kg or more']);" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Why? Describe in words your explanation for this behavior." - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. Run the demo and ask the following **observation questions** :\n", " * What it the height of the point at which the jeans are suspended for a counterweight of 3kg?\n", " * What it the height of the point at which the jeans are suspended for a counterweight of 6kg?\n", " * What it the height of the point at which the jeans are suspended for a counterweight of 20kg?\n", " * What it the height of the point at which the jeans are suspended for a counterweight of 50kg?\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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Virtual demo" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "37fe202298f04300b8a542701e02252b", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(HBox(children=(Label(value='Mass of the counterweight ($kg$):', layout=Layout(margin='5px 10px'…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "from lib.suspendedobjects import *\n", "\n", - "SuspendedObjectsLab();" + "SuspendedObjectsLab(m_object = 3);" ] }, { "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": [ "---\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/suspendedobjects.py). \n", "\n", "## Use of the virtual demo\n", "\n", "Execute the cell below to see the documentation:" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "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.5\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[0mget_angle_from_masses\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mget_angle_from_masses\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7faf123e56a8\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mget_object_coordinates\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mfunction\u001b[0m \u001b[0mget_object_coordinates\u001b[0m \u001b[0mat\u001b[0m \u001b[0;36m0x7faf12408950\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\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", - "\n", - ":get_angle_from_masses: function to compute the angle that the cable makes with the horizon, as a function of the respective masses of the object and the counterweight -- angle(m_object, m_counterweight)\n", - ":get_object_coordinates: function to compute the coordinates of the point at which the object is suspended on the cable -- coord(angle, x_origin, y_origin, distance, height)\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" - } - ], + "outputs": [], "source": [ "SuspendedObjectsLab?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Utility computation function\n", "\n", "By executing the following cell, you will see the code of the function used to compute the angle that the line makes with the horizon depending on the masses of the object and the counterweight. \n", "This function can be redefined and given as parameter when initializing the lab." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mget_angle_from_masses\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm_object\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm_counterweight\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[0mget_angle_from_masses\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm_object\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm_counterweight\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 Compute the angle that the cable makes with the horizon depending on the counterweight chosen\u001b[0m\n", - "\u001b[0;34m angle = arcsin(1/2 * m_object / m_counterweight)\u001b[0m\n", - "\u001b[0;34m \u001b[0m\n", - "\u001b[0;34m :m_object: mass of the object\u001b[0m\n", - "\u001b[0;34m :m_counterweight: mass of the counterweight\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m :returns: angle that the cable makes with the horizon \u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# default angle value \u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mangle\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpi\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# let's check that there is actually a counterweight\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mm_counterweight\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;31m# then we compute the ratio of masses\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mratio\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0.5\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mm_object\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mm_counterweight\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# we check if the ratio of masses is in the domaine of validity of arcsin ([-1;1]) and compute the angle\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mratio\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mratio\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[0mangle\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marcsin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mratio\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\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mangle\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/suspendedobjects.py\n", - "\u001b[0;31mType:\u001b[0m function\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "get_angle_from_masses??" ] } ], "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-exercise.ipynb similarity index 52% copy from TeachingExamples/SuspendedObjects.ipynb copy to TeachingExamples/SuspendedObjects-exercise.ipynb index 3a5f231..b3e321c 100644 --- a/TeachingExamples/SuspendedObjects.ipynb +++ b/TeachingExamples/SuspendedObjects-exercise.ipynb @@ -1,317 +1,204 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "from ipywidgets import interact, interactive, fixed, interact_manual\n", - "from ipywidgets import HBox, VBox, Label\n", - "import ipywidgets as widgets\n", - "\n", - "%matplotlib inline\n", - "import matplotlib.pyplot as plt\n", - "plt.style.use('seaborn-whitegrid') # global style for plotting" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Suspended objects\n", "\n", - "**Question:** Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram below? \n", + "## The problem\n", + "\n", "\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", - "Select your answer below, then use the virtual lab to determine *order of magnitude* of the mass necessary for the counterweight." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "92be6dce2f1b45cb80dabe6db94b8f24", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Dropdown(description='w', options=(('1,5 kg', 1.5), ('3 kg', 3), ('6 kg', 6), ('20 kg', …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f = lambda w: \"Choice registered: \"+str(w)\n", - "interact(f, w=[('1,5 kg', 1.5), ('3 kg', 3), ('6 kg', 6), ('20 kg', 20), ('50 kg or more', 50)]);" + "## Initial questions\n", + "\n", + "**Question:** Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram below? \n", + "\n", + "#### TODO: here, replace by auto-corrected quiz!!!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Virtual lab" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Parameters of the situation\n", - "m_jeans = 3 # mass of the wet jeans, in kg\n", - "\n", - "distance = 5 # distance between the poles, in m\n", - "height = 1.5 # height of the poles, in m\n", - "\n", - "x_origin = 0 # x coordinate of point of origin of the figure = x position of the left pole, in m\n", - "y_origin = 0 # y coordinate of point of origin of the figure = y position of the lower point (ground), in m" - ] - }, - { - "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Compute the angle that the line makes with the horizon depending on the counterweight chosen\n", - "def get_alpha_from_masses(m_jeans, m_counterweight):\n", - " # default angle value \n", - " alpha = np.pi / 2\n", - " \n", - " # let's check that there is actually a counterweight\n", - " if m_counterweight > 0:\n", - " # then we compute the ratio of masses\n", - " ratio = 0.5 * m_jeans / m_counterweight\n", - "\n", - " # we check if the ratio of masses is in the domaine of validity of arcsin ([-1;1]) and compute the angle\n", - " if ratio >= -1 and ratio <= 1:\n", - " alpha = np.arcsin(ratio)\n", - " \n", - " return alpha\n", - "\n", - "# Update the position of the jean from the angle\n", - "def update_jeans(angle, x_origin, y_origin, distance, height):\n", - " # the jean is midway between the poles\n", - " x_jeans = x_origin + 0.5 * distance\n", - " \n", - " # default y value: the jean is on the ground \n", - " y_jeans = y_origin \n", - " \n", - " # we check that the angle is comprised between horizontal (greater than 0) and vertical (smaller than pi/2)\n", - " if angle > 0 and angle < (np.pi / 2): \n", - " # we compute the delta between the horizon and the point given by the angle\n", - " delta = (0.5 * distance * np.tan(angle))\n", - " # we check that the delta is smaller than the height of the poles (otherwise it just means the jean is on the ground)\n", - " if delta <= height:\n", - " y_jeans = y_origin + height - delta\n", - " \n", - " print(\"height of the point at which the jeans are hanged:\", y_jeans) \n", - " \n", - " return [x_jeans, y_jeans]" + "%matplotlib inline\n", + "from lib.suspendedobjects import *\n", + "SuspendedObjectsLab();" ] }, { - "cell_type": "code", - "execution_count": 5, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ae3dd5d6474241808d12a5e4dea06da3", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='m_counterweight', step=0.5), Output()), _dom_classes…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], "source": [ - "# Create visualisation\n", - "def create_graph(m_counterweight = 0):\n", - " # get angle of line then coordinates of jean\n", - " alpha = get_alpha_from_masses(m_jeans, m_counterweight)\n", - " coord_jeans = update_jeans(alpha, x_origin, y_origin, distance, height)\n", - "\n", - " # Create the figure\n", - " fig, ax = plt.subplots(1, figsize=(12, 4))\n", - " \n", - " # Fix graph to problem boundaries\n", - " ax.set_ylim(bottom = y_origin) # limit bottom of y axis to ground\n", - " ax.set_ylim(top = y_origin + height + .2) # limit top of y axis to values just above height\n", - "\n", - " # Draw poles\n", - " x_pole1 = np.array([x_origin, x_origin])\n", - " y_pole1 = np.array([y_origin, y_origin+height])\n", - " ax.plot(x_pole1, y_pole1, \"b-\")\n", - " x_pole2 = np.array([x_origin+distance, x_origin+distance])\n", - " y_pole2 = np.array([y_origin, y_origin+height])\n", - " ax.plot(x_pole2, y_pole2, \"b-\")\n", - "\n", - " # Draw the hanging line\n", - " x = np.array([x_origin, coord_jeans[0], x_origin+distance])\n", - " y = np.array([y_origin+height, coord_jeans[1], y_origin+height])\n", - " ax.plot(x, y, \"ro-\")\n", - "\n", - "\n", - "# Launch interactive visualisation\n", - "interact(create_graph, m_counterweight=(0, 100, .5)); \n", - "## TODO ideas : draw the forces (tension in cable, resulting tension)" + " \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-lab-work%3F).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conceptual explanation\n", "\n", "TODO" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Analytic explanation\n", "\n", "### Hypotheses and simplifications:\n", "\n", "* the jeans are exactly mid-way between the poles so the tension is equal on both sides of the cable\n", "* we represent the jeasn by the point at which they are suspended\n", "* the cable is considered as rigid (not bended)\n", "* we consider the static equilibrium obtained after changing the weight, once the system is stabilized\n", "\n", "### Resolution\n", "\n", "We are looking for the expression of the mass of the counterweight as a function of the other parameters of the problem.\n", "\n", "\n", "\n", "The forces applied on the *jeans* are the following:\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", "\n", "With the forces: $\\vec F_j + \\vec T_r = 0$\n", "\n", "Using the fact that the tension is equal on both sides of the jeans: $\\vec F_j + 2.\\vec T = 0$\n", "\n", "If we project on $x$ and $y$ axes, we get:\n", "\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", "\n", "$\\left\\{\\begin{matrix} T_x = 0 \\\\ F_{jy} + 2.T_y = 0\\end{matrix}\\right. $\n", "\n", "NB: $T_x = 0$ means that the tension on each side of the jeans cancel out.\n", "\n", "The component of the weight on the y axis is $F_{jy} = - m_j.g$, which gives us:\n", "\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", "So we get:\n", "\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$:\n", "\n", "$T = \\frac{m_j.g}{2.sin(\\alpha)}$ $(1)$\n", "\n", "\n", "On the other hand, the forces applied on the *counterweight* are following:\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", "\n", "With the forces: $\\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", "\n", "With the detail of the weight: $-m_{cw}.g + T = 0$\n", "\n", "Which gives us $T = m_{cw}.g$ $(2)$\n", "\n", "From equations $(1)$ and $(2)$ we get:\n", "\n", "$\\left\\{\\begin{matrix}T = \\frac{m_j.g}{2.sin(\\alpha)} \\\\ T = m_{cw}.g\\end{matrix}\\right. $\n", "\n", "Which allows 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", "$m_{cw} = \\frac{m_j}{2.sin(\\alpha)}$\n", "\n", "For the line to be taut as show on the figure, $\\alpha$ has to be really small i.e. 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", "### Application\n", "\n", "For a pair of wet jeans of $3 kg$ and an angle of $4^\\circ = \\frac{\\pi}{45}$, which is approximately like depicted on the figure, we need to put a counterweight of more than 20 kg!\n", "\n", "You can try out the manual calculation below and check that you get a similar result with the virtual lab above:" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "21.503380539305514\n" - ] - } - ], + "outputs": [], "source": [ "m_j = 3\n", "alpha = np.pi / 45\n", "\n", "m_cw = m_j / (2 * np.sin(alpha))\n", "print(m_cw)" ] + }, + { + "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/suspendedobjects.py).\n", + "\n", + "By executing the following cell, you will see the code of the function used to compute the angle that the line makes with the horizon depending on the masses of the object and the counterweight. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_angle_from_masses??" + ] } ], "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.ipynb index 3a5f231..1d4befd 100644 --- a/TeachingExamples/SuspendedObjects.ipynb +++ b/TeachingExamples/SuspendedObjects.ipynb @@ -1,317 +1,279 @@ { "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "from ipywidgets import interact, interactive, fixed, interact_manual\n", "from ipywidgets import HBox, VBox, Label\n", "import ipywidgets as widgets\n", "\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.style.use('seaborn-whitegrid') # global style for plotting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Suspended objects\n", "\n", "**Question:** Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram below? \n", "\n", "\n", "\n", "Select your answer below, then use the virtual lab to determine *order of magnitude* of the mass necessary for the counterweight." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "92be6dce2f1b45cb80dabe6db94b8f24", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Dropdown(description='w', options=(('1,5 kg', 1.5), ('3 kg', 3), ('6 kg', 6), ('20 kg', …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "f = lambda w: \"Choice registered: \"+str(w)\n", "interact(f, w=[('1,5 kg', 1.5), ('3 kg', 3), ('6 kg', 6), ('20 kg', 20), ('50 kg or more', 50)]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Virtual lab" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Parameters of the situation\n", "m_jeans = 3 # mass of the wet jeans, in kg\n", "\n", "distance = 5 # distance between the poles, in m\n", "height = 1.5 # height of the poles, in m\n", "\n", "x_origin = 0 # x coordinate of point of origin of the figure = x position of the left pole, in m\n", "y_origin = 0 # y coordinate of point of origin of the figure = y position of the lower point (ground), in m" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Compute the angle that the line makes with the horizon depending on the counterweight chosen\n", "def get_alpha_from_masses(m_jeans, m_counterweight):\n", " # default angle value \n", " alpha = np.pi / 2\n", " \n", " # let's check that there is actually a counterweight\n", " if m_counterweight > 0:\n", " # then we compute the ratio of masses\n", " ratio = 0.5 * m_jeans / m_counterweight\n", "\n", " # we check if the ratio of masses is in the domaine of validity of arcsin ([-1;1]) and compute the angle\n", " if ratio >= -1 and ratio <= 1:\n", " alpha = np.arcsin(ratio)\n", " \n", " return alpha\n", "\n", "# Update the position of the jean from the angle\n", "def update_jeans(angle, x_origin, y_origin, distance, height):\n", " # the jean is midway between the poles\n", " x_jeans = x_origin + 0.5 * distance\n", " \n", " # default y value: the jean is on the ground \n", " y_jeans = y_origin \n", " \n", " # we check that the angle is comprised between horizontal (greater than 0) and vertical (smaller than pi/2)\n", " if angle > 0 and angle < (np.pi / 2): \n", " # we compute the delta between the horizon and the point given by the angle\n", " delta = (0.5 * distance * np.tan(angle))\n", " # we check that the delta is smaller than the height of the poles (otherwise it just means the jean is on the ground)\n", " if delta <= height:\n", " y_jeans = y_origin + height - delta\n", " \n", " print(\"height of the point at which the jeans are hanged:\", y_jeans) \n", " \n", " return [x_jeans, y_jeans]" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ae3dd5d6474241808d12a5e4dea06da3", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='m_counterweight', step=0.5), Output()), _dom_classes…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Create visualisation\n", "def create_graph(m_counterweight = 0):\n", " # get angle of line then coordinates of jean\n", " alpha = get_alpha_from_masses(m_jeans, m_counterweight)\n", " coord_jeans = update_jeans(alpha, x_origin, y_origin, distance, height)\n", "\n", " # Create the figure\n", " fig, ax = plt.subplots(1, figsize=(12, 4))\n", " \n", " # Fix graph to problem boundaries\n", " ax.set_ylim(bottom = y_origin) # limit bottom of y axis to ground\n", " ax.set_ylim(top = y_origin + height + .2) # limit top of y axis to values just above height\n", "\n", " # Draw poles\n", " x_pole1 = np.array([x_origin, x_origin])\n", " y_pole1 = np.array([y_origin, y_origin+height])\n", " ax.plot(x_pole1, y_pole1, \"b-\")\n", " x_pole2 = np.array([x_origin+distance, x_origin+distance])\n", " y_pole2 = np.array([y_origin, y_origin+height])\n", " ax.plot(x_pole2, y_pole2, \"b-\")\n", "\n", " # Draw the hanging line\n", " x = np.array([x_origin, coord_jeans[0], x_origin+distance])\n", " y = np.array([y_origin+height, coord_jeans[1], y_origin+height])\n", " ax.plot(x, y, \"ro-\")\n", "\n", "\n", "# Launch interactive visualisation\n", "interact(create_graph, m_counterweight=(0, 100, .5)); \n", "## TODO ideas : draw the forces (tension in cable, resulting tension)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conceptual explanation\n", "\n", "TODO" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Analytic explanation\n", "\n", "### Hypotheses and simplifications:\n", "\n", "* the jeans are exactly mid-way between the poles so the tension is equal on both sides of the cable\n", "* we represent the jeasn by the point at which they are suspended\n", "* the cable is considered as rigid (not bended)\n", "* we consider the static equilibrium obtained after changing the weight, once the system is stabilized\n", "\n", "### Resolution\n", "\n", "We are looking for the expression of the mass of the counterweight as a function of the other parameters of the problem.\n", "\n", "\n", "\n", "The forces applied on the *jeans* are the following:\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", "\n", "With the forces: $\\vec F_j + \\vec T_r = 0$\n", "\n", "Using the fact that the tension is equal on both sides of the jeans: $\\vec F_j + 2.\\vec T = 0$\n", "\n", "If we project on $x$ and $y$ axes, we get:\n", "\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", "\n", "$\\left\\{\\begin{matrix} T_x = 0 \\\\ F_{jy} + 2.T_y = 0\\end{matrix}\\right. $\n", "\n", "NB: $T_x = 0$ means that the tension on each side of the jeans cancel out.\n", "\n", "The component of the weight on the y axis is $F_{jy} = - m_j.g$, which gives us:\n", "\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", "So we get:\n", "\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$:\n", "\n", "$T = \\frac{m_j.g}{2.sin(\\alpha)}$ $(1)$\n", "\n", "\n", "On the other hand, the forces applied on the *counterweight* are following:\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", "\n", "With the forces: $\\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", "\n", "With the detail of the weight: $-m_{cw}.g + T = 0$\n", "\n", "Which gives us $T = m_{cw}.g$ $(2)$\n", "\n", "From equations $(1)$ and $(2)$ we get:\n", "\n", "$\\left\\{\\begin{matrix}T = \\frac{m_j.g}{2.sin(\\alpha)} \\\\ T = m_{cw}.g\\end{matrix}\\right. $\n", "\n", "Which allows 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", "$m_{cw} = \\frac{m_j}{2.sin(\\alpha)}$\n", "\n", "For the line to be taut as show on the figure, $\\alpha$ has to be really small i.e. 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", "### Application\n", "\n", "For a pair of wet jeans of $3 kg$ and an angle of $4^\\circ = \\frac{\\pi}{45}$, which is approximately like depicted on the figure, we need to put a counterweight of more than 20 kg!\n", "\n", "You can try out the manual calculation below and check that you get a similar result with the virtual lab above:" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "21.503380539305514\n" - ] - } - ], + "outputs": [], "source": [ "m_j = 3\n", "alpha = np.pi / 45\n", "\n", "m_cw = m_j / (2 * np.sin(alpha))\n", "print(m_cw)" ] } ], "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/Textbooks.ipynb b/TeachingExamples/Textbooks.ipynb new file mode 100644 index 0000000..c8f0ac9 --- /dev/null +++ b/TeachingExamples/Textbooks.ipynb @@ -0,0 +1,32 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multimedia textbooks - Providing students with rich learning resources" + ] + } + ], + "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 +}