Teaching computational thinking part 4
This is the fourth post in what may be a never ending series on the value of teaching computational and algorithmic thinking. In this one, I’m going to show you the introductory assignment that Danny Caballero and Balachandra Suri put together to introduce high school students to vypthon. And along the way, I’ll try to point out how the assignment not only teaches a totally new way of thinking, it reinforces many traditional physics skills like vector subtraction and components.
Here is the first vpython assignment. The goal of this assignment is to introduce students to vypthon, and the basic objects of the sphere and the arrow. Vpython is just open source module (or visual library) of objects that you can easily call from python.
I can’t describe how powerful it is when the first program you write draws a sphere on the screen and allows you to navigate around the sphere. This is so much more exciting than the “hello world” programs I began with when I was learning to program.
Below the jump, I’ll describe the assignment in more detail, and my students’ very positive reactions to it.
Students get their first real challenge when they are introduced to the arrow object, which looks something like this
The assignment doesn’t tell tell students what the meaning of the various parameters is, and instead, asks them to figure this out. Students pretty readily figure out the meaning of the
posparameter, as the location of the tail, and they even figure out that the vector is broken down into x, y and z components, even though they only started studying components a week or two before. It takes some effort and exploration to understand the meaning of the
axis parameter. At first they want to say that it is simply the coordinates of the tip of the vector, but this isn’t the case, and that can be seen by trying the following code:
Clearly the vector is starting at a position of 0.5 in the x direction, and it points upward a distance of 1.0, so the axis must be a relative vector that points from the tail to the tip. Asking the students to figure out the coordinates of the tip of the vector gives them some quick reinforcement in vector addition.
arrow(pos=vector(2,3,0), axis=vector(-3,6,0), color=color.red)
If we add the axis vector and the position vector, we will get a vector that points from the origin to the tip of the arrow, as shown in the code and picture below.
arrow(pos=vector(0,0,0), axis=vector(-1,9,0), color=color.white)
It’s hard to overstate the joy students find in exploring programming this way. For many, it’s the first time they’ve ever exerted direct control over the computer, and the thought that they could just tell it to draw a sphere or an arrow on the screen is magical. You can see this when they discover how to give objects color. If they let their cursor hover at the statement
color=color. for long enough, a list of options will pop up:
My students were amazed to discover the color “cyan,” which they had never heard about before, and it wasn’t long before they were asking how to make their own colors. All I had to do is say that the computer defines colors in Red, Green, Blue triplets, before they were off experimenting again, creating colors in every shade of the rainbow.
The next exercise for students is to begin to put objects in space, and draw arrows from one to the other. The also learn we can name objects quite simply.
Consider the following code
baseball = sphere (pos=vector (1,3,2),radius=1, color=color.red)
basketball = sphere (pos=vector(-2,-4,-2), radius =3, color=color.blue)
How would you create a vector that points from the baseball (red sphere) to the basketball (blue sphere)? First students explore what the meaning of statements like baseball.pos is by running the code
Note: could python’s syntax be any simpler? I seriously doubt it. Where’s the cout<<baseball.pos I was so used to from C++?
So what would the following line generate?
print baseball.pos ,"-", basketball.pos, "=", baseball.pos-basketball.pos
Now students are starting to really get the idea of vector subtraction, and why it is so easy using components. But they still do not quite understand how to draw a vector from the baseball to the basketball. And here’s another great use for whiteboards while programming. I quickly sketch out the following vectors on the whiteboard.
Here, I ask students to write an expression involving vector addition for this diagram, and they pretty easily come up with . Now I ask them to solve for , and they realize , which is just the displacement vector (final position minus initial position). Then making a vector from the baseball to the basketball becomes a piece o’ cake.
pointer=arrow (pos=baseball.pos, axis = basketball.pos-baseball.pos, color=color.green)
Vector subtraction is this mysterious, difficult thing for most students, but seeing it again in a new context of vpython helps students to further grasp it.
And from there, my students are off and running. “Hey, we could use this to make 3-D models of molecules!” one student said.
Finally, I’ll explain how using just these few simple tools in vpython has the chance to give students a much deeper insight into traditional physics problems.
I recently gave my students the following quiz:
This quiz proved a bit difficult, mostly because my students were fairly new to components, and though they could figure this out using Vector Addition Diagrams (go go graphical understanding) the component notation was a bit tricky.
One of the biggest problems for students in terms of analyzing forces and motion is learning how to make free body diagrams more just “those pictures physics teachers require you to do.” I try to emphasize to my students that their free body diagrams must be to scale, with larger forces getting larger arrows, and if an object if experiencing a net force, this should be readily apparent from the FBD. But all of this becomes much more routine when students can use vpython to create the FBD’s and perform the vector addition.
Let’s start with the code to solve the first problem, where the helicopter is flying horizontally at constant velocity.
from __future__ import division
from visual import *
mcopter = 5000
gvec = g*vector(0,-1,0)
scale = 1/10000
lscale = 1.0 #change this to 1.2 to make lift force 20% bigger
xaxis = arrow(pos=vector(2,0,0), axis=(1,0,0), color = color.white)
yaxis = arrow(pos=vector(2,0,0), axis=(0,1,0), color = color.white)
zaxis = arrow(pos=vector(2,0,0), axis=(0,0,1), color = color.white)
xaxis2 = arrow(pos=vector(-2,0,0), axis=(1,0,0), color = color.white)
yaxis2 = arrow(pos=vector(-2,0,0), axis=(0,1,0), color = color.white)
zaxis2 = arrow(pos=vector(-2,0,0), axis=(0,0,1), color = color.white)
Fg=arrow(pos=vector(-2,0,0), axis=scale*mcopter*gvec, color = color.green, fixedwitdth=true)
Fr=arrow(pos=vector(-2,0,0), axis=scale*vector(-1.9*10**4,0,0), color = color.green,fixedwitdth=true)
Fl=arrow(pos=vector(-2,0,0), axis=lscale*scale*vector(+1.9*10**4,mcopter*g,0), color = color.green,fixedwitdth=true)
Fr2=arrow(pos=Fg2.pos+Fg2.axis, axis=Fr.axis, color=color.green,fixedwitdth=true)
Fl2=arrow(pos=Fr2.pos+Fr2.axis, axis=Fl.axis, color=color.green,fixedwitdth=true)
This program draws a free body diagram on the left and then a vector addition diagram showing the sum of the forces on the right, and if there is a net force, it will be drawn in red. Also notice how easy it is to sum the forces in the last line of code to compute Fnet.
Run this code and you get this:
But the real power comes in making the making the following modification to 7th line of code
lscale = 1.0 #change this to 1.2 to make lift force 20% bigger
In python it’s easy to increase only the lift force and see what happens. Here’s what the program produces:
Clearly there’s a net force here, since the vector addition diagram doesn’t add to zero, and though it’s hard to see, there’s a tiny red arrow pointing in the same direction as the lift force on the right hand diagram.
Finally, its fairly easy to see that if only want to accelerate in the x direction, you need a net force that points only in the x direction, and this requires you to modify only the horizontal component of the lift force, with this line, with the important change in bold.
Fl=arrow(pos=vector(-2,0,0), axis=scale*vector(+1.9*10**4+20000,mcopter*g,0), color = color.green)
Run the code again, and you get this:
Of course, I put this code together, since my students had just started out with vpython a few days earlier. However, I don’t think it’s out of the question, that if we’d started off with python right at the same time we started the course, and had practice in using it to visualize problems all along the way, students would have had no trouble making this simulation, giving them one more ‘arrow’ in their model building quiver to build understanding. Sure, it’d probably be much easier just to have the students draw the free body diagrams in word or some painting program, but now we’re only one or two steps removed from putting the helicopter in motion, and watching as it accelerates. And imagine what you could do then—create a simulation of a car traveling around a banked turn, and then at the click of a button, draw in the force vectors acting on the car? Click another button, and watch as those vectors magically add themselves head to tail and show you the net force on the car is pointing inward? How cool would that be?
Next step for part 5: lesson 2: objects moving with constant velocity and the motionmodel.py package.