I so liked how the tree of life turned out the last time I tried it, that I did it again this year with a significant improvement in the use of rubber bands.
Students chose organisms and then looked up their classification — Wikipedia quite reliable for this — then they wrote the names down on synchronized chips of colored paper. As usual, they preferentially chose charismatic, mammalian, megafauna, but there was also a squid, and for two people who did not come up with anything themselves, I assigned a plant (elm), and a bacteria (the one that causes strep throat).
The actual color pattern of the chips does not matter, but I used red for Domain, yellow for Kingdom, green for Phylum, pink for Class, red for Order, yellow for Family, green for Genus, and pink for species. The colors repeated, and I liked how that helped organize the pattern of the final result.
In class, using a pin-board, I used push pins to place homo sapiens on the board. I linked the push pins with rubber bands, which makes for a nicer, sharper pattern than using string, and is easier to do.
To get a nice pattern I then asked who had the closest relative to humans. It took a little effort to figure it out, but I decided to go with a degrees-of-separation metric. Basically, I asked them to count up the classification system to see how many levels they’d have to go to get to something their species shared with humans. The closest were at the Class level: mammals.
Then, starting with the students with the lowest separation distance, I had the students come up to the board and add their organism to the growing tree.
Later, during lunch, a student asked me what was the difference between bison and buffalo. I didn’t know, but another teacher pointed out that one was from North America and the other from Africa. So I asked two of my middle schoolers to look up the classification of american bison and water-buffalos, which we subsequently added to the tree, and which got me thinking about how we might use the rate of separation of the two continents to figure out how fast genetic variation develops.
Today I grew, and then killed off, a bunch of bacteria using the VAMP exponential growth model to talk about exponential and logarithmic functions in pre-Calculus. I also took the opportunity to use an exponential decay model to talk about the development of drug resistance in bacteria.
Students had already worked on, and presented to each other, a few bacterial growth problems but the sound and the animation helped give a better conceptual understanding of what was going on.
After watching and listening to the simulation I asked, “What happens to the doubling time?” and one student answered, “It gets shorter,” which seems reasonable but is incorrect. I was able to explain that the doubling time stays the same even though the rate of reproduction (the number of new cells per second) increases rapidly.
Then I changed the model from growth to decay by changing the doubling time to a half-life. Essentially this changes the coefficient in the exponent of the growth equation from positive to negative. The growth rate’s doubling time was 100 seconds, but I used a half life of 50 seconds for decay to accelerate things a bit, but still show the persistence of the last of the bugs.
The cells died really fast in the beginning, and while there was just one cell was left at the very end, it was pretty clear just how persistent that last cell was; cells were dieing so slowly at the end.
This is similar to what happens when someone takes antibiotics. The typical course lasts for 10 days, but you’ve killed enough of the bacteria to loose the symptoms of sickness after two or three. Those final few that remain are the most resistant to the antibiotic, and if you don’t kill them then, once you stop taking the antibiotic, they’ll start to grow and replicate and you’ll end up sick again with a new, antibiotic-resistant population of bacteria.
I thought that using the VAMP model for the demonstration worked very well. The sound of the cells popping up faster and faster with exponential growth seemed to help amplify the visual effect, and make the whole thing more real. And during the decay phase, having that last cell hang on, seemingly forever, really helped convey the idea that bacteria can be extremely persistent.
American bison (Bison bison) are native to North America, while water buffalo (Bubalus bubalis) are from Africa. They are different species, and each are classified in a different genus, however, they belong to the same Family, Bovidae. Since it’s highly unlikely that there was any genetic intermingling after Africa separated from North America, if we can figure out how long ago the two continents were together, we can estimate how long ago their common ancestor lived, and how fast evolution occurs (at least in large mammals).
Continental Rifting
North America is moving away from Africa at an average spreading rate of about 2.5 cm/year, and the continents are about 4550 km apart.
To figure out how long it has been since the continents were together, we need to convert the distance into the same units as the spreading rate and then divide by the rate.
Converting the distance to cm:
Finding the time:
So we get 182 million years.
Evolutionary Rates
Now to get really back-of-the-envelope. If it takes 182 million years to be separated by two levels of classification (the genus and species levels), then it takes approximately 91 million years for each level of classification.
If we extend this backwards up the phylogenetic tree (species –> Genus –> Family –> Order –> Class –> Phylum –> Kingdom ), which is probably illegal, we get a grand total of six levels of classification back to the divergence of the plant and animal kingdoms. That’s 546 million years, which is remarkably close to the time of the first fossil records of complex multi-cellular life, somewhere near the beginning of the Cambrian about 540 million years ago.
The major caveat, however, is that the first phylogenetic step, from Domain to Kingdom took a lot longer than our 91 million year average, since the first life appeared on Earth about 4 billion years ago.
Conclusion
There are lots of issues with this analysis, but the result is curiously coincidental. I’d really appreciate any thoughts on the validity of this particular exercise.
Note:
The spreading happens at the Mid-Atlantic Ridge, which bifurcates the Atlantic. However, if you look at a map of the bathymetry of the North Atlantic, you can see long striations — lines — that show the direction of the tectonic plate motion. The distance the continents moved are best measured along this line.
The problem with global climate change and agriculture not only that it will probably make it harder to grow crops as the continents dry, but also that where you can grow thing will also change as ecological regions shift. Places where there are long traditions of crops such as sugar maples and cranberries will have to adapt, and often, adapting isn’t easy. This article from Marketplace looks at cranberries in Massachusetts.
For my programming elective, I thought I’d try to get students programming autonomous agents that we could all compile together into some type of game. Since it was, for most of them a first class in programming, this has proven a little too ambitious, and I’ve had to adjust a bit to build up to it.
Step 1: Build a spaceship/vehicle/agent.
We’re using VPython so we can build 3d ships. Students get to exercise their creativity a bit and learn how to place things in 3d co-ordinate space.
The ship must have a front end and all the parts must be put into a single frame so the whole thing can be moved as a unit.
Although it’s not required, I’ve added in the beginnings of a trail so we can track the motion of the spaceship
from visual import *
f = frame()
r = ring(frame=f, thickness=.25, axis=(0,1,0))
cabin = sphere(frame=f, radius=0.6, color=color.red)
front = pyramid(frame=f, height=1,width=1,length=2, color=color.blue)
trail = curve(pos=[f.pos,])
Step 2: Make the spaceship a class.
Putting the spaceship in a separate class, away from the rest of the code, makes it easier to move from one program to another. That means we can import everyone’s ships into a single program at the end.
We’re going to control the movement of the spaceship using the arrow keys. Left and right to turn; up and down to accelerate and decelerate.
To allow movement, we’ll put the keyboard controls into an infinite loop, but to allow maximum flexibility (and to show how to use create methods in a class) we’re putting the actual movement in as methods in the class: the turning method is named turn_xz and movement is move_xz since all the motion is going to be restricted in the xz plane for now.
from visual import *
class spaceship1:
def __init__(self):
self.f = frame()
self.r = ring(frame=self.f, thickness=.25, axis=(0,1,0))
self.cabin = sphere(frame=self.f, radius=0.6, color=color.red)
self.front = pyramid(frame=self.f, height=1,width=1,length=2, color=color.blue)
self.trail = curve(pos=[self.f.pos,])
def turn_xz(self, turn_rate):
self.f.axis = rotate(self.f.axis, turn_rate, (0,1,0))
def move_xz(self, speed):
self.f.pos = self.f.pos + self.f.axis*speed
self.trail.append(pos=self.f.pos)
ss = spaceship1()
turn = 0.0
speed=0.0
while 1:
rate(20) #slows down execution of the loop
ss.turn_xz(turn)
ss.move_xz(speed)
if scene.kb.keys: # event waiting to be processed?
s = scene.kb.getkey() # get keyboard info
if s == 'left':
turn = turn + 0.01
if s == 'right':
turn = turn - 0.01
if s == 'up':
speed = speed + 0.01
if s == 'down':
speed = speed - 0.01
if s == ' ':
if turn <> 0:
turn = 0
elif speed <> 0:
speed = 0
Fire missiles
We add in missiles by creating a class very similar to the spaceship. For now our missile is just a ball but I’m putting it into a frame anyway in case later on I want it to be a composite object.
Since we can fire multiple missiles, in the code I create a list to hold all the missiles.
Missiles are fired using the “a” key.
from visual import *
class spaceship1:
def __init__(self):
self.f = frame()
self.r = ring(frame=self.f, thickness=.25, axis=(0,1,0))
self.cabin = sphere(frame=self.f, radius=0.6, color=color.red)
self.front = pyramid(frame=self.f, height=1,width=1,length=2, color=color.blue)
self.trail = curve(pos=[self.f.pos,])
def turn_xz(self, turn_rate):
self.f.axis = rotate(self.f.axis, turn_rate, (0,1,0))
def move_xz(self, speed):
self.f.pos = self.f.pos + self.f.axis*speed
self.trail.append(pos=self.f.pos)
class missile:
def __init__(self, axis, pos):
self.f = frame(axis=axis, pos=pos)
self.r = sphere(frame=self.f, radius=0.2, color=color.green)
self.speed = 0.5
def move_xz(self):
self.f.pos = self.f.pos + self.f.axis*self.speed
ss = spaceship1()
turn = 0.0
speed=0.0
missiles = [] #list for missiles
while 1:
rate(20) #slows down execution of the loop
ss.turn_xz(turn)
ss.move_xz(speed)
#move missiles
for i, m in enumerate(missiles):
m.move_xz()
if scene.kb.keys: # event waiting to be processed?
s = scene.kb.getkey() # get keyboard info
if s == 'left':
turn = turn + 0.01
if s == 'right':
turn = turn - 0.01
if s == 'up':
speed = speed + 0.01
if s == 'down':
speed = speed - 0.01
if s == ' ':
if turn <> 0:
turn = 0
elif speed <> 0:
speed = 0
#fire missile
if s == 'a':
missiles.append(missile(ss.f.axis, ss.f.pos))
Final adjustments
Finally, I’m going to put in a boundary, and set it up to delete the missiles if they go out of bounds.
I’m also going to set an option so that the scene follows the ship, which makes it easier to keep track of things.
from visual import *
class spaceship1:
def __init__(self):
self.f = frame()
self.r = ring(frame=self.f, thickness=.25, axis=(0,1,0))
self.cabin = sphere(frame=self.f, radius=0.6, color=color.red)
self.front = pyramid(frame=self.f, height=1,width=1,length=2, color=color.blue)
self.trail = curve(pos=[self.f.pos,])
def turn_xz(self, turn_rate):
self.f.axis = rotate(self.f.axis, turn_rate, (0,1,0))
def move_xz(self, speed):
self.f.pos = self.f.pos + self.f.axis*speed
self.trail.append(pos=self.f.pos)
class missile:
def __init__(self, axis, pos):
self.f = frame(axis=axis, pos=pos)
self.r = sphere(frame=self.f, radius=0.2, color=color.green)
self.speed = 0.5
def move_xz(self):
self.f.pos = self.f.pos + self.f.axis*self.speed
class bounds:
def __init__(self, boundary_distance):
self.boundary_distance = boundary_distance
self.border = curve(pos=[(-boundary_distance,0,-boundary_distance),
(boundary_distance,0,-boundary_distance),
(boundary_distance,0,boundary_distance),
(-boundary_distance,0,boundary_distance),
(-boundary_distance,0,-boundary_distance)])
def in_bounds(self, pos):
if ( pos.x < -self.boundary_distance or
pos.x > self.boundary_distance or
pos.z < -self.boundary_distance or
pos.z > self.boundary_distance):
return false
else:
return true
ss = spaceship1()
turn = 0.0
speed=0.0
l_track_ship = 1
scene.range=10
scene.forward = (0,-1,0)
missiles = []
boundary_distance = 100
boundary = bounds(boundary_distance)
while 1:
rate(20)
if l_track_ship > 0:
scene.center = ss.f.pos
ss.turn_xz(turn)
ss.move_xz(speed)
#move missiles
del_list = []
for i, m in enumerate(missiles):
m.move_xz()
#delete missile if out of bounds
if boundary.in_bounds(m.f.pos) == False:
del_list.append(i)
for i in del_list:
missiles[i].f.visible = False
del missiles[i]
#if m <> None:
# m.move_xz()
if scene.kb.keys: # event waiting to be processed?
s = scene.kb.getkey() # get keyboard info
if s == 'left':
turn = turn + 0.01
if s == 'right':
turn = turn - 0.01
if s == 'up':
speed = speed + 0.01
if s == 'down':
speed = speed - 0.01
if s == ' ':
if turn <> 0:
turn = 0
elif speed <> 0:
speed = 0
#fire missile
if s == 'a':
missiles.append(missile(ss.f.axis, ss.f.pos))
Next steps
Now that we’re cooking with charcoal — we have a functioning program — the next steps will be setting up a target to shoot at, and, if the students are ready, letting them program their ships to move autonomously. If they’re not ready then, as an example, I’ll program some opposition.
Ian Simpson has an interesting article on the movement to reduce the numbers of the invasive snakehead fish more appealing to restaurants and their customers.
[Snakeheads have] dense, meaty, white flesh with a mild taste that is ideal for anything from grilling to sauteing.
…
[But] the fish are air breathers that can last for days out of water. Even when gutted and with their throats cut, they gape for breath, said John Rorapaugh, director of sustainability and sales at ProFish, a Washington wholesaler.
“Once they get to mature size, they are on top of the food chain and are ravenous,” he said.
…
Josh Newhard, an expert on the snakehead with the U.S. Fish and Wildlife Service, said it was too early to say what the snakehead’s long-term impact would be on its invaded environment. … “The potential is really high for them to impact other fish species. The fact that people want to remove them from the system is really good,” he said.
My middle-school students are reading Janet Kagan’s short story, “The Loch Moose Monster” as part of our discussion about genetics, ecology and educational environments. This article makes a nice complement.
There’s a trail that runs along the forested ridge above the school. With summer phasing into fall, and the smell of winter in the air, I decided to offer cross-country running as my P.E. option this quarter.
Just getting to the ridge-top is a strenuous jog up a steep slope (note to self: I need to get the geometry students to calculate the slope), especially with the thick, slippery layer of this fall’s accumulated leaves to test the unwary, and I was a little surprised that about half a dozen students actually took me up on it.
Indeed a few more students have accreted onto our group since we started, casualties of the other P.E. options for the most part. But I’d like to think that the beauty of the wooded landscape — brilliant elm and sugar maple leaves littering the ground; crisp, cool air against flushed skin; the fresh, decisive smells in the ridge-top air; the crack an crackle of leaves underfoot — may have also attracted some attention.
I’m looking forward to observing how the slope and forest change with the coming winter.
Go back in time and see who would have won the last presidential election. BuzzFeed has an excellent set of maps showing who would have won the election if voting was restricted as it was in the past.
The video below gives a quick history of when voting rights were extended to different demographic groups.