We went through simple harmonic motion derivations two days ago in AP. Writing the second-order diff eq. was easy for them, but it was the first one that they've solved, so we had a nice long guess-and-check for possible solutions. Ultimately, it was pretty clear to them how to take that trig function and get what they needed from it, but the process of using that diff. eq. solution as a model to solve similar ones (especially the hanging spring) was more difficult for them. I don't have any awesome inspirations on teaching that, but looking at a few other situations (two springs, etc.) helped quite a bit, and I assigned the "fall through the Earth" problem last night, which is a great application of SHM.
The point here, though, is to talk about some of the realizations about SHM that they had, and how Python helped that happen. They don't do oscillations in their first course, so this is the first that they've seen it in a physics context. The idea of amplitude independence is always tricky for students, so I just let them make a prediction about what would happen to the period of a spring when I changed the mass, or the spring constant, the amplitude, or g.
It's easy enough to see those results by looking at the derived period function, but it was always difficult to demonstrate some of those things cleanly - springs wobble, students imagine slightly different periods, they can't tell exactly what the amplitude or equilibrium point are (and damping doesn't help), I can't turn off gravity, etc.
I modified our second programming assignment of the year to have two springs instead of one, and demonstrated all of those cases very easily. Because they know how the program works (they basically wrote it), there's more faith in it (well, not faith, since it's based on reason, but they put more stock in it), and it's much easier to see. The springs will oscillate perfectly forever and I can listen more to the discussion than worry about restarting the springs all the time.
Here's the script - use with attribution and an email:
from visual import *
Fscale = .1
ball1=sphere(radius=.1, color=color.green, pos=(-.5,-.5,0), velocity=vector(0,0,0))
ball2=sphere(radius=.1, color=color.orange, pos=(.5,-.7,0), velocity=vector(0,0,0))
#ballvvec=arrow(pos=ball.pos, color=color.blue, axis=vscale*ball.velocity,shaftwidth=.05)
spring1 = helix(pos = roof1.pos, coils=15, axis=(ball1.pos-roof1.pos),radius=.1)
spring2 = helix(pos = roof2.pos, coils=15, axis=(ball2.pos-roof2.pos),radius=.1)
# physical constants
k = 20
restlength = 1
while 5 <= 10:
springforce1 = -k * (mag(spring1.axis)-restlength) * spring1.axis / mag(spring1.axis)
netforce1 = gravity1 + springforce1
springforce2 = -k * (mag(spring2.axis)-restlength) * spring2.axis / mag(spring2.axis)
netforce2 = gravity2 + springforce2
# v and r update
ball1.velocity = ball1.velocity + netforce1 * deltat / mass1
ball1.pos = ball1.pos + ball1.velocity * deltat
ball2.velocity = ball2.velocity + netforce2 * deltat / mass2
ball2.pos = ball2.pos + ball2.velocity * deltat
# vector and graphical updates
#ballvvec.pos = ball.pos
#ballvvec.axis = vscale*ball.velocity
#forcevec.pos = ball.pos
#forcevec.axis = Fscale*netforce
# time update
t = t + deltat