diff --git a/TeachingExamples/Demonstrations.ipynb b/TeachingExamples/Demonstrations.ipynb index 36e4352..e3787fa 100644 --- a/TeachingExamples/Demonstrations.ipynb +++ b/TeachingExamples/Demonstrations.ipynb @@ -1,89 +1,98 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Virtual demonstrations - Using digital artefacts to illustrate 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", + "Classroom demonstrations are among students’ favorite elements of introductory science classes and they are well known from teachers to stimulate students’ interest and motivation. \n", "Jupyter Notebooks allow you to design very easily **virtual demonstrations** to show students **things that you could not demonstrate in real life**. \n", "\n", - "But how to ensure that your demonstrations are **more than just entertainment**?\n", - "\n", + "But how to ensure that your demonstrations are **more than just entertainment**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "## Essential ingredients of virtual demonstrations\n", "### Using \"prediction questions\"\n", "\n", "Catherine Crouch and her colleagues at Harvard University (C. Crouch, Fagen, Callan, & Mazur, 2004) were interested in knowing whether the demonstrations traditionally used in introductory science courses were really helping students to learn. More specifically, they wanted to know if there were ways to use classroom demonstrations that would help students better understand than others. \n", "So they tested three different ways of using demonstrations in a large introductory physics class (133 students), and assessed students' understanding of the underlying concepts at the end of the semester.\n", "\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", "\n", "\n", - "TODO multiple representations\n", - "\n", + "TODO multiple representations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "## Examples of virtual demonstrations for teaching\n", "\n", "You can show students virtual demonstrations in Jupyter Notebooks in class. As seen above, asking your students prediction questions before showing them the demo will make your virtual demonstrations more effective.\n", "Below are examples of simple virtual demonstrations which include prediction questions in different formats.\n", "\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", "
In classHomework exercise
Suspended objectsThis 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 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" + "https://aapt.scitation.org/doi/10.1119/1.1707018" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git a/TeachingExamples/FallingObjects-exercise.ipynb b/TeachingExamples/FallingObjects-exercise.ipynb index 188086b..be214b2 100644 --- a/TeachingExamples/FallingObjects-exercise.ipynb +++ b/TeachingExamples/FallingObjects-exercise.ipynb @@ -1,318 +1,335 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook is about demonstrating:\n", "* How to make a **demonstration available to students** in the form of an **exercise including different types of questions**\n", "* Using notebook cells to encourage students to **take notes** when they use a virtual demonstration\n", "\n", "The example chosen is voluntarily *simple* so that anyone can understand what is illustrated and focus the pedagogical features of the example.\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Falling objects \"apple \n", "\n", "## The problem \n", "We **drop** an object from a given height with **no initial velocity**. Just like an apple would fall from a tree. \n", "We consider the movement of the object, **ignoring resistance from the air**.\n", "\n", " \n", "\n", "## Initial questions\n", "\n", "Answer the following questions _before_ using the virtual lab.\n", "\n", "**Question 1:** Which object would reach the ground first: a bowling ball (5 kg) or a tennis ball (0.05 kg)? Write down your answer in the cell below." ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question 2:** Why? In the cell below, describe in words your explanation for this behavior." ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Tip:* In physics, as in many disciplines, sketching your ideas can really help you figure out problems. \n", "It might be a good idea to take a piece of paper and sketch what you think the following variables will look like as a function of time: the *height* of the object, the *velocity* of the object and the *acceleration* of the object." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "## Virtual lab\n", "The virtual demonstration below illustrates the movement of different objects. \n", "Execute the cell below to launch the virtual demonstration, then *answer the questions below*." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "from lib.fallingobjects import *\n", "FallingObjectsLab(show_withair=False);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "**Question 1:** Choose an initial height that will be the same for all the objects you will observe, e.g. 5 meters. \n", "When does the each object reaches the ground? \n", "Note down the time in seconds below." ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Object 1 reaches the ground at:\n", "### Object 2 reaches the ground at:\n", "### Object 3 reaches the ground at:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Tip:* Actually, the interactive figure allows you to plot the movement of several objects simultaneously by maintaining the 'ctrl' key selected while clicking with your mouse on the objects you want to display. \n", "Try to select several objects to display simultaneously.\n", "\n", "**Question 2:** What can you conclude from this experiment? \n", "*If you wonder how the virtual lab works and would like to see the code, [you can have a look at it at the end of this notebook](#How-does-the-virtual-lab-work%3F).*" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "## Synthesis\n", "\n", "**Question 1:** How does your own explanation compare with the explanation provided below?" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Problem analysis\n", "\n", "\n", "We are looking for the time at which the object will reach the ground. Therefore *we are looking for an equation giving us the height of the object as a function of time*.\n", "\n", "We know the initial height and velocity of the object, as well as its mass. \n", "In addition, if we ignore the friction from air, we know that the only force applied on the object is the weight: $\\vec F = m \\vec g$\n", "\n", "#### Movement of the object\n", "Since there is only one force involved, it seems quite straightforward to use Newton's second law: $\\sum \\vec F = m \\vec a$\n", "\n", "With the weight the only force on the object, we get: $\\vec F = m \\vec a$ \n", "Using the expression of the weight it gives us: $m \\vec g = m \\vec a$ \n", "Therefore the movement of the object is described by $\\vec a = \\vec g$.\n", "\n", "To get the equation of acceleration as a function of time, we project onto our coordinate system: $a = -g$, therefore $a(t) = -g$. \n", "This means that the ball is under **constant acceleration**.\n", "\n", "From there we can get the equations for velocity and height by integrating successively: \n", "$\\left\\{\\begin{matrix} a(t) = -g \\\\ v(t) = -g\\,t + v_0 \\\\ h(t) = -\\frac{1}{2}\\,g\\,t^2 + v_0\\,t + h_0\\end{matrix}\\right. $\n", "\n", "The above equations have the following parameters:\n", "* the initial height $h_0$ from which the object is dropped\n", "* the initial velocity of the object $v_0$, with $v_0 = 0$ when the object is dropped with no initial velocity\n", "* and of course the acceleration due to gravity $g$\n", "\n", "#### Conclusion\n", "We see clearly that **the mass $m$ of the object plays no role at all in the equations of the movement**.\n", "\n", "**Question 2:** What happens if we don't ignore the resistance of the air?" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Question 3:** Why is it reasonable to ignore the resistance of the air in this situation? \n", + "Execute the cell below, then click on the button to show the effect of friction from the air. \n", + "Select different objects to see how they are affected depending on their characteristics." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "FallingObjectsLab();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Question 3:** When is it reasonable to ignore the resistance of the air and why? \n", "List the criteria that you could you to decide if resistance from the air can be ignored or not when solving a problem." ] }, { "cell_type": "raw", "metadata": {}, "source": [ "### Type your answer here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", " \n", "\n", "---\n", "\n", "## How does that look in real life?\n", "\n", "The following video demonstrates how a bowling ball and ostrich feathers fall in a vacuum chamber, thus illustrating how what we have seen so far looks in the real world." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import YouTubeVideo\n", "YouTubeVideo('E43-CfukEgs', 560, 315)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "---\n", "## How does the virtual lab work?\n", "\n", "You can have a look at the code of the virtual lab by [opening this python file](lib/fallingobjects.py). \n", "By executing the following three cells, you will see the code of the three functions used to compute the movement equations for the falling object.\n", "\n", "#### Code of $a(t) = -g$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "accel_time??" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Code of $v(t) = -g\\,t + v_0$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "veloc_time??" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Code of $h(t) = -\\frac{1}{2}\\,g\\,t^2 + v_0\\,t + h_0$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "height_time??" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "---\n", "\n", "## Other resources on the web\n", "\n", "Detailed explanations with examples on falling objects: https://opentextbc.ca/physicstestbook2/chapter/falling-objects/\n", "\n", "Impact of air resistance on falling objects (in French): http://www.physagreg.fr/mecanique/m12/M12-chute-libre-frottements.pdf" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git a/TeachingExamples/SuspendedObjects-demo.ipynb b/TeachingExamples/SuspendedObjects-demo.ipynb index a03263d..46f7c24 100644 --- a/TeachingExamples/SuspendedObjects-demo.ipynb +++ b/TeachingExamples/SuspendedObjects-demo.ipynb @@ -1,148 +1,145 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook is about demonstrating:\n", "* using **different types of questions** to engage students with the virtual demonstration\n", "* using **different types of visualizations** to help students understand the phenomena\n", "\n", "The example chosen is voluntarily *simple* so that anyone can understand what is illustrated and focus the pedagogical features of the example.\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 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", " * Estimate which counterweight allows to suspend wet jeans (3kg) on the cable so that the cable is taut as shown on the diagram?\n", " * 1,5 kg\n", " * 3 kg\n", " * 6 kg\n", " * 20 kg\n", " * 50 kg or more\n", " * Why? Describe in words your explanation for this behavior.\n", " " ] }, { "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 is the height of the point at which the jeans are suspended for a counterweight of 3kg? 6kg? 20kg? 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": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "from lib.suspendedobjects import *\n", "SuspendedObjectsLab();" ] }, { "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": null, "metadata": {}, "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": 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-exercise.ipynb b/TeachingExamples/SuspendedObjects-exercise.ipynb index 9542ede..bd4d025 100644 --- a/TeachingExamples/SuspendedObjects-exercise.ipynb +++ b/TeachingExamples/SuspendedObjects-exercise.ipynb @@ -1,205 +1,226 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook is about demonstrating:\n", "* making a demonstration available to students in the form of an exercise including **auto-corrected quizzes**\n", "* using **different types of visualizations** to help students understand the phenomena\n", "\n", "The example chosen is voluntarily *simple* so that anyone can understand what is illustrated and focus the pedagogical features of the example.\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Suspended objects\n", "\n", "## The 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", "## 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", + "#### TODO: here, replace by auto-corrected quiz!!!\n", "\n", - "#### TODO: here, replace by auto-corrected quiz!!!\n" + "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", + "* 1,5 kg\n", + "* 3 kg\n", + "* 6 kg\n", + "* 20 kg\n", + "* 50 kg or more\n", + "\n", + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Virtual lab" + "## Virtual lab\n", + "\n", + "The virtual demonstration below illustrates position of the clothesline for different counterweights. \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.suspendedobjects import *\n", "SuspendedObjectsLab();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "#### TODO here add observation questions in the form of auto-corrected quizzes.\n", + "\n", " \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", + "*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", - "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", + "* 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", - "We are looking for the expression of the **mass of the counterweight as a function of the other parameters of the problem**.\n", + "We are looking for the expression of the **mass of the counterweight as a function of the other parameters of the problem**. \n", + "Given that the system is in static equilibrium, using Newton's second law should be easy (sum of external forces will be zero) and we will have the mass of the counterweight involved in the expression of the force it exerts on the system.\n", "\n", + "First, let's draw a diagram and represent the different forces involved.\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", "With the forces involved in our problem we get: $\\vec F_j + \\vec T_r = 0$ \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", "$\\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$: \n", "$T = \\frac{m_j.g}{2.sin(\\alpha)}$ $(1)$\n", "\n", " \n", "\n", - "On the other hand, the forces applied on the *counterweight* are following:\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", "Using the expression of the weight: $-m_{cw}.g + T = 0$ \n", "Which gives us $T = m_{cw}.g$ $(2)$\n", "\n", + " \n", + "\n", "From equations $(1)$ and $(2)$ we get: \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", "$m_{cw} = \\frac{m_j}{2.sin(\\alpha)}$\n", "\n", + " \n", + "\n", + "### Conclusion\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", "\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", + "### Application\n", "\n", - "You can try out the manual calculation below and check that you get a similar result with the virtual lab above:" + "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "m_j = 3\n", - "alpha = np.pi / 45\n", - "\n", - "m_cw = m_j / (2 * np.sin(alpha))\n", - "print(m_cw)" + " 3 / (2 * np.sin(np.pi / 45))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can **check that you get a similar result** with the virtual lab above!" ] }, { "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/lib/suspendedobjects.py b/TeachingExamples/lib/suspendedobjects.py index 431e4c0..7d9aa78 100644 --- a/TeachingExamples/lib/suspendedobjects.py +++ b/TeachingExamples/lib/suspendedobjects.py @@ -1,221 +1,221 @@ import numpy as np from scipy.interpolate import interp1d from ipywidgets import interact, interactive, fixed, interact_manual from ipywidgets import 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 ###--- Functions depending on the problem parameters def get_angle_from_masses(m_object, m_counterweight): """ Compute the angle that the cable makes with the horizon depending on the counterweight chosen angle = arcsin(1/2 * m_object / m_counterweight) :m_object: mass of the object :m_counterweight: mass of the counterweight :returns: angle that the cable makes with the horizon """ # default angle value angle = np.pi / 2 # let's check that there is actually a counterweight if m_counterweight > 0: # then we compute the ratio of masses ratio = 0.5 * m_object / m_counterweight # we check if the ratio of masses is in the domaine of validity of arcsin ([-1;1]) and compute the angle if ratio >= -1 and ratio <= 1: angle = np.arcsin(ratio) return angle def get_object_coordinates(angle, x_origin, y_origin, distance, height): """ Computes the position of the object on the cable taking into account the angle determined by the counterweight and the dimensions of the hanging system. By default: - the object is supposed to be suspended exactly in the middle of the cable - the object is on considered the ground for all values of the angle :angle: angle that the cable makes with the horizon :x_origin: x coordinate of the bottom of the left pole (origin of the coordinate system) :y_origin: y coordinate of the bottom of the left pole (origin of the coordinate system) :distance: horizontal distance between the two poles :height: height of the poles (same height for both) :returns: coordinates of the point at which the object are hanged """ # the jean is midway between the poles x_object = x_origin + 0.5 * distance # default y value: the jean is on the ground y_object = y_origin # we check that the angle is comprised between horizontal (greater than 0) and vertical (smaller than pi/2) if angle > 0 and angle < (np.pi / 2): # we compute the delta between the horizon and the point given by the angle delta = (0.5 * distance * np.tan(angle)) # we check that the delta is smaller than the height of the poles (otherwise it just means the jean is on the ground) if delta <= height: y_object = y_origin + height - delta return [x_object, y_object] class SuspendedObjectsLab: """ 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. """ def __init__(self, m_object = 3, distance = 5, height = 1.5, x_origin = 0, y_origin = 0, get_angle_from_masses = get_angle_from_masses, get_object_coordinates = get_object_coordinates): ''' Initiates and displays the virtual lab on suspended objects. :m_object: mass of the suspended object :distance: horizontal distance between the two poles :height: height of the poles (same height for both) :x_origin: x coordinate of the bottom of the left pole (origin of the coordinate system) :y_origin: y coordinate of the bottom of the left pole (origin of the coordinate system) :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) :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) ''' ###--- Parameters of the situation self.m_object = m_object # mass of the wet object, in kg self.distance = distance # distance between the poles, in m self.height = height # height of the poles, in m self.x_origin = x_origin # x coordinate of point of origin of the figure = x position of the left pole, in m self.y_origin = y_origin # y coordinate of point of origin of the figure = y position of the lower point (ground), in m # Functions to compute equations self.get_angle_from_masses = get_angle_from_masses self.get_object_coordinates = get_object_coordinates ###--- Then we define the elements of the ihm: # parameters for sliders self.m_counterweight_min = 0 self.m_counterweight_max = 100 self.m_counterweight = self.m_counterweight_min # initial mass of the counterweight (0 by default, no counterweight at the beginning) # IHM input elements input_layout=Layout(margin='5px 10px') self.m_counterweight_label = Label('Mass of the counterweight ($kg$):', layout=input_layout) self.m_counterweight_widget = widgets.FloatSlider(min=self.m_counterweight_min,max=self.m_counterweight_max,step=1,value=self.m_counterweight, layout=input_layout) self.m_counterweight_input = HBox([self.m_counterweight_label, self.m_counterweight_widget]) # IHM output elements self.y_object_output = widgets.Output(layout=input_layout) self.graph_output = widgets.Output(layout=input_layout) # Linking widgets to handlers self.m_counterweight_widget.observe(self.m_counterweight_event_handler, names='value') # Organize layout self.ihm = VBox([self.m_counterweight_input, self. y_object_output, self.graph_output]) ###--- 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 m_counterweight_event_handler(self, change): self.m_counterweight = change.new self.update_lab() # Create visualisation def update_lab(self): # Clear outputs self.graph_output.clear_output(wait=True) self.y_object_output.clear_output(wait=True) # get angle of cable then coordinates of jean alpha = self.get_angle_from_masses(self.m_object, self.m_counterweight) coord_object = self.get_object_coordinates(alpha, self.x_origin, self.y_origin, self.distance, self.height) # Create the figure - fig, ax = plt.subplots(1, 3, figsize=(16, 4)) + fig, ax = plt.subplots(1, 3, figsize=(14, 4)) ###--- First display the clothesline ax[0].set_title('Clothesline') # Fix graph to problem boundaries ax[0].set_ylim(bottom = self.y_origin) # limit bottom of y axis to ground ax[0].set_ylim(top = self.y_origin + self.height + .2) # limit top of y axis to values just above height # Draw poles x_pole1 = np.array([self.x_origin, self.x_origin]) y_pole1 = np.array([self.y_origin, self.y_origin+self.height]) ax[0].plot(x_pole1, y_pole1, "k-", linewidth=7) x_pole2 = np.array([self.x_origin+self.distance, self.x_origin+self.distance]) y_pole2 = np.array([self.y_origin, self.y_origin+self.height]) ax[0].plot(x_pole2, y_pole2, "k-", linewidth=7) # Draw the hanging cable x = np.array([self.x_origin, coord_object[0], self.x_origin+self.distance]) y = np.array([self.y_origin+self.height, coord_object[1], self.y_origin+self.height]) ax[0].plot(x, y, "g-") # Draw the point at which the object is suspended ax[0].scatter(coord_object[0], coord_object[1], s=80, c="r", zorder=15) ###--- Then display the the angle and the height as functions from the mass of the counterweight - ax[1].set_title('Angle of the cable compared to horizon (degrees$^\circ$)') - ax[2].set_title('Height of the point at which the object is hanged ($m$)') + ax[1].set_title('Angle of the cable vs. horizon ($^\circ$)') + ax[2].set_title('Height of the suspension point ($m$)') # Create all possible values of the mass of the counterweight m_cw = np.linspace(self.m_counterweight_min, self.m_counterweight_max, 100) # Compute the angle (in degrees) and height for all these values angle = [] height = [] for m in m_cw: a = self.get_angle_from_masses(self.m_object, m) angle.append(a*180/np.pi) c = self.get_object_coordinates(a, self.x_origin, self.y_origin, self.distance, self.height) height.append(c[1]) # Display the functions on the graphs ax[1].set_xlabel('Mass of the counterweight (kg)') ax[1].plot(m_cw, angle, "b") ax[2].set_xlabel('Mass of the counterweight (kg)') ax[2].plot(m_cw, height, "b") # Add the current angle from the counterweight selected by the user ax[1].scatter(self.m_counterweight, alpha*180/np.pi, s=80, c="r", zorder=15) # Add the current height from the counterweight selected by the user ax[2].scatter(self.m_counterweight, coord_object[1], s=80, c="r", zorder=15) # Display height of object selected with self.y_object_output: print("Height of the point at which the object is hanged (m):", coord_object[1]) # Display graph with self.graph_output: plt.show(); # EOF