Posts Tagged ‘education’

Capo 2

Capo 2 from SuperMegaUltraGroovy just came out, and it’s a huge leap forward from Version 1. The basic functions for learning a piece of recorded music are still there. You can:

The big improvement is the addition of a spectrogram to help you figure out which notes are playing. The spectrogram has replaced the waveform in the main panel of the Capo window (click to see a full-sized screenshot).

A waveform, seen in programs like Fission and Audacity, plots the intensity of sound on the vertical axis against time on the horizontal axis. Capo’s spectrogram plots frequency on the vertical axis against time on the horizontal (intensity is indicated by how dark the marks are). This allows you to see the notes that are being played.

Below the spectrogram is a tablature bar. Clicking and dragging over a note in the spectrogram

  1. puts a gray bar on top of it (as I’ve done with the first three notes);
  2. plays it as a piano note so you can hear if you picked the right one; and
  3. puts a fret indicator on the appropriate string down in the tablature.1

This is a great way to use a computer to figure out a song. It makes Capo 1, which I really liked, seem useless.

Not using conventional tuning? Capo lets you choose from over 50 tunings. Looking to learn the bass part instead? Capo can do bass tablature, too (and mandolin and ukelele2). Developer Chris Liscio made it possible for ordinary humans to create their own instrument/tuning tablature templates and his beta testers responded with a ton of tunings.

Capo isn’t perfect at figuring out notes. Strictly speaking, its spectral analysis picks out the frequencies present, not the notes. Harmonics can generate several frequencies for a single note, and you’ll still need to use your ear to figure out where the note is. But the spectrogram certainly makes your job much easier.

Much of what Capo 2 can do is implicit in the user interface (this is my polite way of saying that what Capo can do isn’t immediately obvious). Released with Capo is a set of short tutorial videos that show how to use it. These are much better than any written description and can be accessed from within Capo itself from the Welcome to Capo item in the Help menu.

(That screenshot reminds me: Capo can figure out chords, too.)

There are some annoyances:

The biggest problem with Capo, though, is that it came along too late. If I had had this back in college, when I had more time on my hands, I might actually have become a decent guitar player.


  1. Yes, most notes have more than one fret/string combination. Capo makes what it thinks is the conventional choice, but allows you to move it to a different combination by clicking on the bar you just drew with the Option key down. 

  2. Ukelele?! Boing Boing should be all over this. 


Clock practice for kids update

For reasons I can’t explain, my original post on printing time/clock practice sheets for kids always forced you to download a zipped archive of files to your local computer, unzip them in some convenient place, and launch them from your hard drive. While this is no burden to my geekier readers (who might prefer a local copy they can edit to suit their own needs), it’s not the sort of thing the average parent or teacher is used to doing.

So here’s a direct link to a page that shows the clock faces without the download/unzip hassle. Every time you load or reload the page a new set of 12 clock faces will appear, which you can then print out to give your young scholar some practice in telling time.

The minute hand moves in five-minute increments, so it’s not for kids who are first learning to tell time, it’s for those who have mastered “o’clock” and “half past.”

I should mention again that the JavaScript that generates the clock hands is largely based on this work by Mathieu ‘P01’ Henri and his analog clock page.

If you have kids the right age, you might be interested in my other grade school math practice sheets, covering addition, subtraction, multiplication and division.


Podcast cannibalism

Well here’s an unfortunate bit of convergence. The Science Show, a radio show about—you guessed it—science from ABC Radio National in Australia, has decided to rebroadcast episodes of Radiolab, a radio show about science from WNYC in New York. This is great for Science Show fans from the antipodes who listen over the air, because Radiolab is an excellent show. But it’s unfortunate for me1 because I listen to both shows via podcast, and now there’ll be less original content.

It’s not that The Science Show will stop producing its own stories and be given over entirely to old Radiolab programs, but that’s what happened this week, with a rebroadcast of the “Parasites” show, and is scheduled to happen next week, with a rebroadcast of the “Stochasticity” show.

A story in the “Stochasticity” episode, about coin flipping and the odds of generating runs of consecutive heads or tails, was of particular interest to me, ultimately inspiring four separate blog posts. Worth listening to, if you haven’t already.


  1. And me is all I really care about. 


Division practice sheet

The school year is almost over, so here’s something your kids will love to play with over the summer: a division practice page that generates a new set of problems every time you refresh. Yippeee!

It’s set up like my other math practice sheets, a self-contained HTML file with all the JavaScript and CSS included. Use it from the web or download it to your computer—your browser will open it either way. Each time you open the page (or refresh it), you get a new bunch of problems. Print them out and give them to your grade-schoolers to practice with.

Every problem is a 4-digit number divided by a 2-digit number. The numerals are big and the space below each problem should be enough for the lines of long division. The problems do not necessarily have integer quotients; this is for kids who know about remainders.

Here’s the bad news: every browser will be able to open the file, but not all browsers will display it nicely. To get that nice curved line between the dividend (the big number) and the divisor (the small number) to meet the horizontal line above the dividend, I had to do some things with CSS that aren’t supported in older versions of Internet Explorer. So if you’re using a version older than IE 8, the problems won’t render correctly. You really shouldn’t be using those older versions of IE, anyway.

Worse, even the browsers that understand standard CSS render things a little differently with regard to character heights and page margins. To account for that, I’ve made three versions of the file:

I believe that either the Chrome or Safari version will work with IE 8, but since I don’t have a Windows machine, I can’t test it.

If you can fix the printing problems with the non-Safari versions, I’d like to hear about it.


Head links

Links, of course, make the web go round. They put the Hyper in HTML. But today the links I found were made in my head, the old-fashioned way.

The day started with me riding in to work listening to The Science Show podcast from ABC Radio National. That’s ABC, as in Australian Broadcasting Corporation, not the folks who bring you Dancing With The Stars. I’m not sure why the Commonwealth countries can’t come up with more original network names, but there you go.

One of the stories in the current Science Show episode is about climate change’s affect on mountain-dwelling reptiles and amphibians in Madagascar. Chris Raxworthy of the American Museum of Natural History has been studying how certain populations have been gradually shifting their habitats to higher elevations as temperatures have increased. The concern is that eventually they’ll move to the tops of the mountains and have nowhere else to go. Wait a minute, I thought, didn’t I just read about this? Yes, it’s the same problem discussed by Chris Clarke in his most recent Coyote Crossing post, although the mountains he talks about are in the American Southwest. My first link of the day.

Another current Science Show story is about a highly portable chemical analysis instruments developed by Emily Hilder of the University of Tasmania. Much of the story is about the use of these devices by bomb squads, but there’s a later mention of using them for early detection of Tasmanian devil facial tumor disease (DFTD). As an American, when I hear about Tasmanian devils, I can’t help but smile and think of Warner Brothers, but this disease, a facial cancer that looks horrible, has killed 80-90% of the devil population in some areas. Where’s the link here? Patience.

(This Science Show episode also has an audio essay by David Attenborough about salamanders. I can’t think of any connection to salamanders, so it doesn’t fit in with the theme of this post, but the essay is informative and entertaining in that way Attenborough always seems to be, so I felt I had to mention it. Best line: “Salamanders I’m afraid are not really very quick on the uptake.”)

By the time The Science Show had ended, I was at work, where I spent eight or nine hours doing things of no interest to anyone. Then it was time to ride home, and I fired up the most recent episode of Radiolab, the sciencey radio show/podcast with Robert Krulwich and Jad Abumrad. The current episode is entitled “Famous Tumors,” and one of the stories is about, yes, Tasmanian devil facial tumor disease.1 The description of the disease is both fascinating and creepy. Apparently, tumors taken from different devils are genetically identical—the cancer is, in effect, a single organism that grows by spreading from one host to another.

So, two podcasts created on opposite sides of the world. I listen to both of them on the same day and they both talk about tumors on Tasmanian devils. Weird.

The final Radiolab story is about Henrietta Lacks, the woman whose cells—which came to be known as the HeLa line—taken during a biopsy, were the first human cells to be successfully grown and maintained in a laboratory. It’s based on The Immortal Life of Henrietta Lacks, a recent book by Rebecca Skloot, who does some of the narration. The Radiolab story and the book cover not only the importance of the HeLa line to medical advances in the 20th century (it was heavily used, for example, in the development of the polio vaccine), but how the knowledge that Henrietta’s cells lived on after her death affected her family.

I haven’t actually read The Immortal Life of Henrietta Lacks, but it’s on my list of books to read because it’s been praised often by Tom Levenson on his Inverse Square Blog, one of my favorite RSS subscriptions. He’s also the author of Newton and the Counterfeiter, an excellent book I have read,2 because most of my professional life—that eight or nine hours we skipped over—involves adapting and applying Newton’s Laws, and I have a longstanding interest in Newtoniana.

The Henrietta Lacks story ended as I arrived home, where I expected to be greeted by James Burke.


  1. I told you we’d get to a link. 

  2. I also listened to Tom give a talk on the book at Fermilab a couple of months ago. He’s an excellent speaker—able hold an audience’s interest without props or slides. 


Iridium flares in iCal

Last summer I wrote a script that logged in to my account at Heaven’s Above every Monday morning and emailed me a list of the week’s upcoming Iridium flares. The script has been working perfectly, but I’ve found myself doing the same things every time I read the email:

These are purely mechanical steps and are better done by a program than by me. So here’s my new Iridium script, called iridium-calendar, which automates the entire process.

 1:  #!/usr/bin/env python
 2:  
 3:  import mechanize
 4:  from time import strftime
 5:  from BeautifulSoup import BeautifulSoup
 6:  from datetime import datetime, date, timedelta
 7:  from time import strptime
 8:  from appscript import *
 9:  
10:  # Add an event to my "home" calendar with an alarm 15 minutes before.
11:  def makeiCalEvent(start, loc):
12:    end = start + timedelta(0, 60)
13:    evt = app('iCal').calendars['home'].events.end.make(new=k.event,
14:      with_properties={k.summary:'Iridium flare', k.start_date:start, k.end_date:end, k.location:loc})
15:    evt.sound_alarms.end.make(new=k.sound_alarm,
16:      with_properties={k.sound_name:'Basso', k.trigger_interval:-15})
17:  
18:  # Parse a row of Heaven's Above data and return the start date (datetime),
19:  # the intensity (integer), and the sky position (string).
20:  def parseRow(row):
21:    cols = row.findAll('td')
22:    dStr = cols[0].string
23:    tStr = ':'.join(cols[1].a.string.split(':')[0:2])
24:    intensity = int(cols[2].string)
25:    alt = cols[3].string.replace('°', '')
26:    az = cols[4].string.replace('°', '')
27:    loc = 'alt %s, az %s' % (alt, az)
28:    startStr = '%s %s %s' % (dStr, date.today().year, tStr)
29:    start = datetime(*strptime(startStr, '%d %b %Y %H:%M')[0:7])
30:    return (start, intensity, loc)
31:  
32:  # Heaven's Above URLs and login information.
33:  lURL = 'http://heavens-above.com/logon.asp'                       # login
34:  iURL = 'http://heavens-above.com/iridium.asp?Dur=7&Session='      # iridium flares
35:  user = {'name' : 'user',  'password' : 'seekret'}
36:  
37:    
38:  # Create virtual browser and login.
39:  br = mechanize.Browser()
40:  br.set_handle_robots(False)
41:  br.open(lURL)
42:  br.select_form(nr=0)    # the login form is the first on the page
43:  br['UserName'] = user['name']
44:  br['Password'] = user['password']
45:  resp = br.submit()
46:  
47:  # Get session ID from the end of the response URL.
48:  sid = resp.geturl().split('=')[1]
49:  
50:  # Get the 7-day Iridium page.
51:  iHtml = br.open(iURL + sid).read()
52:  
53:   
54:  # For some reason, Beautiful Soup can't parse the HTML on the Iridium page.
55:  # To get around this problem, we extract just the table of flare data and set
56:  # it in a well-formed HTML skeleton.
57:  table = iHtml.split(r'<table BORDER CELLPADDING=5>')[1]
58:  table = table.split(r'</table>')[0]
59:  
60:  html = '''<html>
61:  <head>
62:  </head>
63:  <body>
64:  <table>
65:  %s
66:  </table>
67:  </body>
68:  </html>''' % table
69:  
70:  # Parse the HTML.
71:  soup = BeautifulSoup(html)
72:  
73:  # Collect only the data rows of the table.
74:  rows = soup.findAll('table')[0].findAll('tr')[1:]
75:  
76:  # Go through the data rows, adding only bright evening events to my "home" calendar.
77:  for row in rows:
78:    (start, intensity, loc) = parseRow(row)
79:    if intensity <= -5 and start.hour > 12:
80:      makeiCalEvent(start, loc)

All the logging-in and data gathering in Lines 31-50 are the same as before. The new stuff is in the two functions, makeiCalEvent and parseRow, and in Lines 53-79 of the main program.

In writing makeiCalEvent, I leaned heavily on this article on making an iCal to-do at Clark’s Tech Blog and on the ASTranslate application from the appscript people. The code is not what you’d call elegant, mainly because iCal’s AppleScript dictionary is an awkward mess.

The parseRow function has lots of fiddly bits, because it needs to

The result, though is pretty clean: an iCal entry with an alarm and enough information to be looking in the right place when the flare appears.

The iCal entry itself isn’t so important, as I’m almost never at my computer when the Iridium alarm goes off. What’s important is that these entries get synced to my iPhone, and my iPhone sounds the alarm 15 minutes before the flare does its thing. Here’s what the alarm looks like on the phone:

I don’t run iridium-calendar myself—that’s something for the computer to remember. I have launchd run it every Monday morning at 6:00 AM via this plist file, called com.leancrew.iridium.plist, in my ~/Library/LaunchAgents folder:

 1:  <?xml version="1.0" encoding="UTF-8"?>
 2:  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3:  <plist version="1.0">
 4:  <dict>
 5:   <key>KeepAlive</key>
 6:   <false/>
 7:   <key>Label</key>
 8:   <string>com.leancrew.iridium</string>
 9:   <key>ProgramArguments</key>
10:   <array>
11:     <string>/Users/drang/bin/iridium-calendar</string>
12:   </array>
13:   <key>StartCalendarInterval</key>
14:   <dict>
15:     <key>Hour</key>
16:     <integer>6</integer>
17:     <key>Minute</key>
18:     <integer>0</integer>
19:     <key>Weekday</key>
20:     <integer>1</integer>
21:   </dict>
22:  </dict>
23:  </plist>

I still have Lingon generate launchd configuration files, even though its author, Peter Borg, stopped developing it a while ago. It’s easy to use and doesn’t make typos. The one thing I dislike about Lingon is its message telling you to go through a log out/log in cycle to get your new agent installed. That’s not necessary; instead, use the launchctl command to load and unload agents as you develop them.