Teaching Programming Online at Khan Academy

92dfeb863138a5a9c0453ed80f9c8c75?s=47 Pamela Fox
October 23, 2013

Teaching Programming Online at Khan Academy

A talk given at USC about what Khan Academy is, where our technical challenges lie, featuring a deep dive on how we teach the programming curriculum.

92dfeb863138a5a9c0453ed80f9c8c75?s=128

Pamela Fox

October 23, 2013
Tweet

Transcript

  1. 2.

    My Background Computer Science Linguistics 3d Animation + + Developer

    Relations 2002 2007 2007 2011 2012 2013 Frontend Engineer Wednesday, October 23, 13
  2. 11.
  3. 16.

    So many options Languages Uses Java Python C++ Haskell JavaScript

    Ruby Scheme Games Animation Hardware Robotics Data Science Simulation Mobile Websites Lua Wednesday, October 23, 13
  4. 18.

    So many options Languages Uses Java Python C++ Haskell JavaScript

    Ruby Scheme Games Animation Hardware Robotics Data Science Simulation Mobile Websites Lua Wednesday, October 23, 13
  5. 25.

    JSHint var myName = “spaghetti if (i == 0) {

    } var i = 2; if (i == 0) { } errors warnings best practices Wednesday, October 23, 13
  6. 27.

    Infinite Loop Checker var i = 0; while(i < 10)

    { ellipse(i, i, 30, 30); } Web Worker Wednesday, October 23, 13
  7. 30.

    Our approach: “talk-throughs” Uses same environment they program in Making

    passive instruction interactive! https://www.khanacademy.org/cs/programming/drawing-basics/p/intro-to-drawing Wednesday, October 23, 13
  8. 31.

    Playing talk-throughs SoundManager2.js commands = [ {"key": "\n", "time": 14124},

    {"key": "\n", "time": 14260}, {"key": "r", "time": 14676}, {"key": "e", "time": 14764}, {"key": "c", "time": 15036}, {"key": "t", "time": 15548},...] <audio> or <object> var player = soundManager.createSound({ url: revision.getMp3Url(), whileplaying: function() { updateTimeLeft(Record.currentTime()); Record.trigger("playUpdate"); } }); Wednesday, October 23, 13
  9. 33.

    Recording audio var multirecorder = new MultiRecorder(); multirecorder.startRecording(); https://github.com/Khan/MultiRecorderJS/blob/master/multirecorder.js rightBuffer.push(stream[0]);

    leftBuffer.push(stream[1]); getUserMedia() new Worker() multirecorder.stopRecording(); getInterleaved(); encodeWAV(); Wednesday, October 23, 13
  10. 36.

    Our approach: coding challenges Structured yet flexible. More than one

    way to code the solution. Wednesday, October 23, 13
  11. 40.

    StructuredJS http://khan.github.io/structuredjs/index.html var $numVar = $numVal; if ($numVar > 0)

    { rect($x, $y, $w, $h); } var theNumber = 10; fill(255, 255, 255); if (theNumber > 0) { rect(10, 10, 30, 40); } if (theNumber < 0) { rect(10, 50, 30, 40); } structure: user code: it’s a match! Wednesday, October 23, 13
  12. 41.

    staticTest staticTest(“Add the ifs!”, function() { var descrip = “Now

    add an if to check if the number is positive.”; var pattern = function() { var $numVar = $numVal; if ($numVar > 0) { rect($x, $y, $w, $h); } }; result = match(pattern); if (passes(result)) { var goodX = structure(pattern, inRange(“$x”, 10, 20)); if (!matches(goodX)) { result = fail(“Hm, does your rect start on the side?”); } } assertMatch(result, descrip, displayP); }); Wednesday, October 23, 13
  13. 42.

    ...Not quite that simple, though! Most challenge tests are hundreds

    of lines long. Most steps have 10-20 helpful messages. https://www.khanacademy.org/cs/challenge-exploding-sun/2050946856 Wednesday, October 23, 13
  14. 48.

    Wilson Voting Algorithm, GAE’d def wilson_confidence(upvotes_name, downvotes_name, score): """Lower bound

    of Wilson score 90% confidence interval. This is the algorithm Reddit uses to sort comments. You should not use this if downvotes are disallowed - it is only useful in the presence of both upvotes and downvotes because its ranking is based on an estimate of the ratio of upvotes to downvotes. See http://www.evanmiller.org/how-not-to-sort-by-average-rating.html """ upvotes = getattr(score, upvotes_name) downvotes = getattr(score, downvotes_name) if upvotes == 0: return -downvotes elif upvotes == downvotes: return 0 n = upvotes + downvotes z = 1.64485 # 90% confidence z-score phat = float(upvotes) / n # p-hat return ((phat + z * z / (2 * n) - z * math.sqrt((phat * (1 - phat) + z * z / (4 * n)) / n)) / (1 + z * z / n)) class TimeIndependentScoreProperty(ndb.ComputedProperty): def __init__(self, upvotes_name="upvotes", downvotes_name="downvotes", **kwargs): super(TimeIndependentScoreProperty, self).__init__( functools.partial(wilson_confidence, upvotes_name, downvotes_name), **kwargs) Wednesday, October 23, 13
  15. 51.

    Reddit Voting Algorithm, GAE’d def time_dependent(decay_seconds, upvotes_name, downvotes_name, created_name, score):

    """Ranking based on both age and quality. This is the algorithm Reddit uses to sort stories. We want there to be churn, a constant stream of new programs hitting the hot page, so this algorithm takes into account both the score of the scratchpad and the age. See http://amix.dk/blog/post/19588 """ s = getattr(score, upvotes_name) - getattr(score, downvotes_name) # Weight votes logarithmically - initial votes are worth a ton order = math.log(max(abs(s), 1), 10) sign = 1 if s > 0 else -1 if s < 0 else 0 # Seconds since this algorithm's start date date = getattr(score, created_name) or datetime.datetime.now() seconds = epoch_seconds(date) - 1349108492 return round(order + sign * seconds / decay_seconds, 7) class TimeDependentScoreProperty(ndb.ComputedProperty): def __init__(self, decay_seconds, upvotes_name="upvotes", downvotes_name="downvotes", created_name="created", **kwargs): super(TimeDependentScoreProperty, self).__init__(functools.partial( time_dependent, decay_seconds, upvotes_name, downvotes_name, created_name), **kwargs) Wednesday, October 23, 13
  16. 59.

    Software Developer Intern Mobile Developer Intern Data Scientist Intern Product

    Designer Intern Intern Roles Wednesday, October 23, 13