Teaching Programming Online (CodeMotion)

92dfeb863138a5a9c0453ed80f9c8c75?s=47 Pamela Fox
November 22, 2014

Teaching Programming Online (CodeMotion)

A talk delivered at CodeMotion about teaching programming online on Khan Academy.

92dfeb863138a5a9c0453ed80f9c8c75?s=128

Pamela Fox

November 22, 2014
Tweet

Transcript

  1. 2.

    My Background Computer Science Linguistics 3d Animation + + Developer

    Relations 2002 ! ! ! 2007 2007 ! ! ! 2011 2012 ! 2013 Frontend Engineer
  2. 12.
  3. 14.

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

    Ruby Scheme Games Animation Hardware Robotics Data Science Simulation Mobile Websites Lua
  4. 16.

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

    Ruby Scheme Games Animation Hardware Robotics Data Science Simulation Mobile Websites Lua
  5. 21.

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

    ! } var i = 2;! if (i == 0) {! ! } errors warnings best practices
  6. 23.

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

    {! ellipse(i, i, 30, 30);! } Web Worker
  7. 26.

    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
  8. 27.

    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");! }! });
  9. 38.

    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!
  10. 39.

    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);! });!
  11. 40.

    ...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
  12. 41.

    How we improve challenges Challenges Attempted: 244,168 ! Challenges Completed:

    162,858 ! Challenge Completion Rate: 67% Overall Analytics
  13. 47.

    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)! !
  14. 50.

    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)!
  15. 51.

    Similarity Diffing diff = difflib.SequenceMatcher(! # Ignore differences in spacing!

    isjunk=lambda x: x in " \t\n",! a=origin_revision.code.strip(),! b=self.revision.code.strip(),! autojunk=True)! ! # Compute the ratio difference between the two revisions! # If the code is really large then we just do a quick ratio! # instead to try and speed up the comparison! if (len(origin_revision.code) > max_ratio_size or! len(self.revision.code) > max_ratio_size):! similarity = diff.quick_ratio()! else:! similarity = diff.ratio() Uh oh, Re-posts!