What does a Khan Academy coach and class intern do besides drink from an unlimited supply of Diet Dr. Pepper and meet Bill Gates?

I've had the chance to work with hugely passionate and skilled people to help teachers trick students into learning. Once a week, everyone makes a list of the things they accomplished so that everyone knows what everyone else is doing. I'm including mine below in the hope that you will see how much freedom Khan Academy interns have and how awesome the experience can be. I got to be part of a talented and dedicated team that is changing and improving the way people learn. 

I went from absolutely no experience in web design to writting our most used and blogged-about report in four weeks thanks to all of the support I was given. If you would like to do similar stuff, you should apply.

Snippets for the week of April 29, 2013

- Joined the team
- Got setup
- Added myself to about/our-interns
- Added placeholder text when loading reports with blank classlists
- Working on migrating class reports to bootstrap-daterangepicker
- Working on a sortable per-student grid coach report
- Went to Denver, helped coaches use Khan Academy and get their class signed up
- Also in Denver, got lots of feedback & suggestions for coach reports
- Wrote a report on coach reports - to send out today

Snippets for the week of May 6, 2013

- Worked with Kitt and others to improve the appearance of the upcoming "By Student" coach report
- Became acquainted with KA style guidelines and best practices through a long, ardous, and not-yet-finished review process

Snippets for the week of May 13, 2013

- Merged by-student coach report into master (khanacademy.org/class_profile/progress-by-student)
- Created a protobuf-based hacky data-import tool, imported class data
- Expanded MixPanel analytics for coach reports
- Explored various options for improving performance of by-student report

Snippets for the week of May 20, 2013

- Chased waterfalls
- Continued implementing and polishing by-student report

Snippets for the week of May 27, 2013

- Published the by-student report for all to see
- Started working on unifying date picker

Snippets for the week of June 10, 2013

- Fixed bugs in the "By Student" report as reported on Google Code
- Athena-ized the "By Student", "By Exercise", and "Table" coach reports
- Added an XLSX download tool for the "By Student" report - written entirely client-side
- Participated in the "Coach Assignments" design sprint.
- Infected vim (thanks, Emily!)
- Hiked

Snippets for the week of July 1, 2013

- Refactored a master-detail component out of the student view for coach rec report
- Worked with Maureen to fix a bunch of nits with the coach demo
- Enabled the coach report date picker inside profile reports
- Enabled the new throbber in profile

Snippets for the week of July 8, 2013

- Implemented basic Coach Rec report - http://goo.gl/wv0Fp
- Participated in Coach Rec dogfooding
- Fixed misc coach report bugs
- Climbed Half Dome
- Experimentally verified that complimenting people on their effort is more effective than complimenting people on intrinsic value.

Snippets for the week of July 22, 2013

- Created recommendation tab for by student report
- Made various UI enhancements in coach reports
- Exposed recommendation tab to profile
- Added compressed_and_readable make option
- Enabled IE8 support for By Student report
- Misc bug fixes

Snippets for the week of July 29, 2013

 - Got me some 5 star reviews - http://appworld.blackberry.com/webstore/content/32700889
 - Fixed bugs in By Student > Recommendations report
 - Got stressed out a little too much
 - Mocked up new design for the Coach section of the website (http://goo.gl/866kSX)
 - Refactored code to reflect the fact that the class profile is no longer a
   thing (instead we have "coach reports"). Also replaced references to coach
   profile and class/coach dashboards with coach reports.
 - Implemented the new filter bar
 - Profiled the Coach tab loading process - we spend about 2 seconds in
   dependency hell and another 3 jumping between filter events.
 - Refactoring coach reports to avoid the above two problems

The Problem

One of the common requests the Coach and Class team (we’re the team that makes tools for teachers) got was to add the ability to download a copy of their students’ data for things like posters or for parent-teacher interview print-outs.

In the end, we want to provide tools so that teachers never have to use the download button, but we'll never hit every feature every teacher wants, so it's a really good thing to have around.

One solution would be to do it asynchronously on the server side and use Google App Engine's blobstore API to create a download. But this is slow and expensive and painful to implement. There's no way to export this data from JavaScript and have it work on all the browsers Khan Academy supports (FF, Chrome, Safari, and IE8+), is there?

The Solution

In fact there is, and I don’t understand why it isn’t used more widely (hence why I’m blogging). It took less than a day to implement an instant and cross-platform data export for the By Student report.

All browsers in common use, including IE8, support this thing called "data URI schemes" (though IE8 has a limit of 32kb). This is often used to embed images right inside a web pages instead of just including a reference to an image which is loaded into the webpage later. So, as an example from Wikipedia, instead of writing:

<img src="redDot.png" />

you can write:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAA

This gets you this: “  ”. Try it yourself. (You’ll notice we use base64 encoding here, but once decoded, everything after the comma is just a PNG file.)

Links are kind of similar -- they are also references to other files, so it's not terribly surprising that you can also use the data URI scheme for links. To download a picture of this red dot, you could just do:

<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAA
HElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" >Click me!</a>

The above code snippet gives you “ Click me! ” Great! So all we need to do is generate a spreadsheet and then create a link like that. Unfortunately, if you do indeed download that (right click -> save as), you might notice that it has a weird filename that doesn’t end with “png” depending on what browser you use (Chrome is nice enough to call it “download.png” but other browsers are not as compassionate). Thankfully, there’s the browser attribute, so you can do:

<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAA
HElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" download="redDot.png">Click me!</a>

Which gives you “ Click me! ”. Sweet! Unfortunately, some browsers don’t support the download attribute so we need to check if it’s supported:

browserSupportsDownloadAttrib: "download" in document.createElement("a"),

and if not, a Google search reveals a cool JS/flash library called Downloadify. Their code sample is all there is to it. Now all we need to do is create a spreadsheet. I initially used Handlebars and zip.js (yes, you read that right - that’s a js libarary which creates zip files) to create an OpenOffice spreadsheet (I did that by saving a basic spreadsheet which turns out to be a zip file, uncompressing it, and modifying the relevant bits)  but it turns out that Office for Mac doesn’t support OpenOffice spreadsheets :( so I ended up using the excellent xlsx.js from Microsoft, which also uses zip.js, by the way.

No, we don't support Safari on iOS.

Try it for yourself here.


I'm part of an incredible team at Khan Academy dedicated to empowering teachers.

Currently over 70 000 teachers¹ actively use KA in their classrooms, but few actually use coach reports. Already we’ve seen how the right kind of insights can transform classrooms, but some of the data has historically been quite difficult to navigate. Since I’ve been at Khan, I’ve met with some of the most active coaches on our site and I’ve been absolutely blown away by both how Khan has already allowed them to help their students and the visions they had of how we can do so much more.

In particular, three questions had to be answered quickly and efficiently:

  • How much work is my class as a whole doing? How effective is that work? Right now, we have reports called “Daily Activity” and “Progress Over Time” to help answer this.
  • Who has become proficient in an assigned exercise? And who is still struggling? Right now, “Progress Summary” and “Progress Report” answer this.
  • How is each student doing? This was the weakest link. Before my first major shipped feature this week, many teachers accessed this information by painstakingly going to individual student profiles. This information was not sortable currently and questions like “How much time is each putting in”, “How many skills have they become proficient in over the last week?”, “How much are they struggling?”, “Is Alice getting her points from doing exercises or watching videos?”, and such were all answered separately.

First, as you can see, the titles of our reports didn’t really give any indication of the questions they were answering. So we gave them more descriptive names:
Secondly, we didn’t adequately answer the third question. When I started three weeks ago, I had little knowledge of JavaScript, Python, or Google App Engine (GAE). Since then, I’ve worked with designers, GAE experts and teachers to get this shipped. I worked on quick iterations, getting features tested sometimes the same day (or hour) as I wrote them, and completely rewrote parts of it until the team and I were completely satisfied with how they answered all the above questions while not being overwhelming. Here is the result:


One challenge was getting the performance we needed, so I spent some time restructuring the report to load as asynchronously as possible. As a result, I went from being worried that we weren't going to be able to ship the product to having one of the fastest coach reports.

And this is why I love my internship:


Try it for yourself!


¹defined as coaches with more than 10 students.