diff --git a/TeachingExamples/01_Demonstrations.ipynb b/TeachingExamples/01_Demonstrations.ipynb index 69a316d..091114c 100644 --- a/TeachingExamples/01_Demonstrations.ipynb +++ b/TeachingExamples/01_Demonstrations.ipynb @@ -1,168 +1,167 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Virtual demonstrations - Using digital artefacts to illustrate explanations\n", "\n", - "Classroom demonstrations, i.e. showing phenomena in class, make great illustrations that stimulate students’ interest and motivation. \n", - "Jupyter Notebooks allow you to design very easily *virtual demonstrations* to show students *things that you could not demonstrate in real life*. \n", + "Classroom demonstrations, i.e. showing phenomena in class, make great illustrations that stimulate students’ interest and motivation. \n", + "Jupyter Notebooks allow you to design very easily *virtual demonstrations* to show students *things that you could not demonstrate in real life*.\n", + "But how to make sure that your demonstrations are **more than just entertainment**?\n", "\n", - "But how to make sure that your demonstrations are **more than just entertainment**? \n", - "A few simple ingredients can transform your virtual demonstrations into *powerful teaching and learning tools*. \n", - "On this page, we summarize briefly some of the ideas from research on the impact of demonstrations on students learning.\n" + "A few simple ingredients can transform your virtual demonstrations into *powerful teaching and learning tools*. On this page, we summarize briefly some of the [ideas from research on the impact of demonstrations on students learning](#Ingredients-for-effective-virtual-demonstrations-in-class) and share with you [example notebooks](#Examples) which implement these ideas in practice.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ingredients for effective virtual demonstrations in class\n", "\n", "### Questions\n", "\n", "Questionning students can really help students engage actively with your demonstration: \n", - "* Catherine Crouch and her colleagues from Harvard University for instance, have shown that having students **predict the outcome of a demonstration before observing it** makes an essential difference in terms of what students remember and understand from a demonstration [(Crouch et al., 2004)](https://aapt.scitation.org/doi/10.1119/1.1707018). This result has been reproduced in a number of other studies, and the reason why this technique works so well seems to be fundamentally linked to how our brain works according to relatively recent models [(Dehaene, 2011)](https://www.college-de-france.fr/site/en-stanislas-dehaene/course-2011-2012.htm). \n", + "* Catherine Crouch and her colleagues from Harvard University for instance, have shown that having students **predict the outcome of a demonstration before observing it** makes an essential difference in terms of what students remember and understand from a demonstration [(Crouch et al., 2004)](https://aapt.scitation.org/doi/10.1119/1.1707018). This result has been reproduced in a number of other studies, and the reason why this technique works so well seems to be fundamentally linked to how our brain works, according to relatively recent models [(Dehaene, 2011)](https://www.college-de-france.fr/site/en-stanislas-dehaene/course-2011-2012.htm). \n", "* When observing a demonstration, it can be hard for students to focus their attention at the right place at the right time. Asking them **questions that drive them to observe specific features** of what you are showing can greatly help them see what you want them to see. \n", "* Very often, students have a hard time identifying what they need to remember from a demonstration. Asking them **questions at the end of a demonstration to reflect on the important points** which have been illustrated is a very effective way to draw their attention to the right elements.\n", "\n", "

In brief: ask students questions before (prediction questions), during (observation questions) and after (reflection questions) your demonstrations.

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Discussions with peers\n", "\n", "Very frequently, the \"why\" things happen is more important than the \"what\" happens in a demonstration. A key to effective demonstrations is therefore to give students an opportunity to formulate why they think things happen that way. \n", "A simple tool to do this is peer discussion. By encouraging students to **discuss the \"why\" with others**, you give them a chance to put words on the implicit model they have in mind and to confront it to the reasoning of others. After verbalizing their understanding of the concepts, students will be better able to assess it against your own explanations, which will then have much more impact.\n", "\n", "

In brief: ask students to discuss the \"why\" with peers before presenting your own explanation.

\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multiple representations\n", "\n", "Presenting students with multiple representations of concepts has been shown to have positive effects on learning [(Mayer, 2009)](http://dx.doi.org/10.1017/CBO9780511811678). Graphical visualizations play an important role in this, but it has been shown that it is the combination of the representations which actually is efficient, which means that *text, equations, tables, videos* or other types of embedded media also are important.\n", "\n", "Two key elements are worth considering particularly in virtual demonstrations:\n", "* Showing explicitely (through visual cues, text, arrows, etc.) **how the different representations relate to each other** is a great way to illustrate different ways of modeling the same reality, which is essential for students to develop their modeling skills.\n", "* Presenting students with the **type of representations that they need to use** when they solve problems in your discipline (for instance when they need to analyze the situation, when they need to choose a model or when they need to check their solution) can help your students develop their problem solving skills \n", "\n", "\n", "

In brief: whenever possible, present your demonstrations with multiple connected representations, which match the representations you want students to use when solving problems.

\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "### Examples\n", "\n", "The following examples show how using the above elements in demonstrations can look like, in different formats:\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", "
What is involved?Show me an example
\"Low tech\"Show the notebook to students, ask them questions where the only thing they have to do is to write their answer on a piece of paper.

Show and make students use visualizations that you want them to use when they solve problems.
Include a video so that students can see how it looks like in reality.
Ask students questions which they have to answer on a piece of paper.

Show visualizations that you want students to use when they solve problems.
Have a look at the falling objects demo
Interactive questionsUse the notebook to poll students using interactive questions where students vote for the answer of their choice.

Combine schematic visualizations with scientific plotting.
Use the notebook to poll students using interactive questions where students vote for the answer of their choice.

Combine and synchronize interactively a diagram and different function plots.
[WORK IN PROGRESS]
Have a look at the suspended objects demo
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "\n", "## Sharing your demonstration notebooks with students\n", "\n", "Making the virtual demonstrations available to the students can be a good idea. But how will students know which parameters to change and what to observe? \n", "By **including questions and instructions** into the notebook together with the virtual demonstration, you will ensure that students can use them effectively in autonomy.\n", "\n", "The following examples are demonstration notebooks extended with questions and instructions for students:\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
What is involved?Show me an example
\"Low tech\"By adding text cells to your notebook, you can transform it into a notebook \"to complete\", in which students write their own explanations and observations.Have a look at the falling objects exercise
Auto-corrected quizzInclude interactive questions into your notebook to augment your notebook with create auto-corrected quizze.Include interactive questions into your notebook to augment your notebook with auto-corrected quizze.[WORK IN PROGRESS]
Have a look at the suspended objects exercise
Computational exerciseAsk your students to modify or complete the code of your demonstration.[WORK IN PROGRESS]
Have a look at the falling objects computational exercise
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \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", "Dehaen, S. (2011). The Statistician Brain: The Bayesian Revolution in Cognitive Sciences. Lectures at Collège de France. \n", "https://www.college-de-france.fr/site/en-stanislas-dehaene/course-2011-2012.htm\n", "\n", "Mayer, R. E. (2009). Multimedia learning (2nd ed.). Cambridge University Press. \n", "http://dx.doi.org/10.1017/CBO9780511811678\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/lib/suspendedobjects.py b/TeachingExamples/lib/suspendedobjects.py index 7d9aa78..4096a94 100644 --- a/TeachingExamples/lib/suspendedobjects.py +++ b/TeachingExamples/lib/suspendedobjects.py @@ -1,221 +1,220 @@ 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=(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) - + ax[0].annotate('m = {} kg'.format(self.m_object), xy=(coord_object[0], coord_object[1]), xytext=(coord_object[0]+0.1, coord_object[1]-0.1)) ###--- Then display the the angle and the height as functions from the mass of the counterweight 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]) + print("Height of the point at which the object is hanged: {:.4f} m".format(coord_object[1])) # Display graph with self.graph_output: plt.show(); # EOF