Teaching Programming Online

  • 269 views
Uploaded on

A talk about how Khan Academy teaches programming online, thanks to App Engine, HTML5, and open source.

A talk about how Khan Academy teaches programming online, thanks to App Engine, HTML5, and open source.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
269
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
8
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • {}

Transcript

  • 1. Teaching Programming Online pamela fox @pamelafox Friday, October 18, 13
  • 2. Friday, October 18, 13
  • 3. What is Khan Academy? Friday, October 18, 13
  • 4. K-12 Subject Tutorials Friday, October 18, 13
  • 5. Exercises & Videos Friday, October 18, 13
  • 6. Personalized Learning Friday, October 18, 13
  • 7. Teacher-facing Analytics Friday, October 18, 13
  • 8. The Tech Stack Backend Frontend Handlebars jQuery Backbone Friday, October 18, 13 LESS FB React
  • 9. Heavy on Open Source Using Contributing Blogging http://bjk5.com/ http://mattfaus.com/ Friday, October 18, 13 https://github.com/Khan
  • 10. Friday, October 18, 13
  • 11. What should we teach, exactly? Friday, October 18, 13
  • 12. So many options Ruby C++ Haskell Scheme Java Python Lua JavaScript Languages Websites Mobile Games Hardware Animation Uses Robotics Simulation Data Science Friday, October 18, 13
  • 13. Our goals No Installation Needed Fun for Anyone Shareable Gateway Drug Friday, October 18, 13
  • 14. So many options Ruby C++ Haskell Scheme Java Python Lua JavaScript Languages Websites Mobile Games Hardware Animation Robotics Simulation Data Science Uses Friday, October 18, 13
  • 15. How do students program? Friday, October 18, 13
  • 16. ACE editor ProcessingJS JSHint ! BabyHint ! Loop Checker Friday, October 18, 13
  • 17. ACE Editor number scrubber Friday, October 18, 13 color picker
  • 18. ACE Editor number scrubber Friday, October 18, 13 color picker
  • 19. ACE Editor number scrubber Friday, October 18, 13 color picker
  • 20. ProcessingJS http://processingjs.org/reference Friday, October 18, 13
  • 21. JSHint var myName = “spaghetti errors if (i == 0) { warnings } best practices var i = 2; if (i == 0) { } Friday, October 18, 13
  • 22. BabyHint elipse(10, 10, 20, 30); spelling ellipse(1, 1, 20, 30, 5); wrong arguments Friday, October 18, 13
  • 23. Infinite Loop Checker var i = 0; while(i < 10) { ellipse(i, i, 30, 30); } Web Worker Friday, October 18, 13
  • 24. Now, how do we teach? Friday, October 18, 13
  • 25. Usual way to teach: Videos https://www.khanacademy.org/science/computer-science/v/python-lists Friday, October 18, 13
  • 26. Our approach: “talk-throughs” Making passive instruction interactive! Uses same environment they program in https://www.khanacademy.org/cs/programming/drawing-basics/p/intro-to-drawing Friday, October 18, 13
  • 27. Playing talk-throughs 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},...] SoundManager2.js var player = soundManager.createSound({ url: revision.getMp3Url(), whileplaying: function() { updateTimeLeft(Record.currentTime()); Record.trigger("playUpdate"); } }); Friday, October 18, 13 <audio> or <object>
  • 28. Creating talk-throughs canvas controls recording controls Friday, October 18, 13
  • 29. Recording audio getUserMedia() var multirecorder = new MultiRecorder(); multirecorder.startRecording(); new Worker() rightBuffer.push(stream[0]); leftBuffer.push(stream[1]); multirecorder.stopRecording(); getInterleaved(); encodeWAV(); https://github.com/Khan/MultiRecorderJS/blob/master/multirecorder.js Friday, October 18, 13
  • 30. How can we assess learning? Friday, October 18, 13
  • 31. Usual way to assess: Exercises Repeated multiple times with variants Friday, October 18, 13
  • 32. Our approach: coding challenges Structured yet flexible. More than one way to code the solution. Friday, October 18, 13
  • 33. ...and they’re fun! Friday, October 18, 13
  • 34. How do we “grade” challenges? staticTest Friday, October 18, 13 StructuredJS Esprima
  • 35. Esprima AST JavaScript var theNumber = 50; if (theNumber > 0) { } http://esprima.org/demo/parse.html# Friday, October 18, 13
  • 36. StructuredJS structure: user code: var $numVar = $numVal; var theNumber = 10; if ($numVar > 0) { rect($x, $y, $w, $h); } fill(255, 255, 255); if (theNumber > 0) { rect(10, 10, 30, 40); } if (theNumber < 0) { rect(10, 50, 30, 40); } it’s a match! http://khan.github.io/structuredjs/index.html Friday, October 18, 13
  • 37. 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); }); Friday, October 18, 13
  • 38. ...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 Friday, October 18, 13
  • 39. How do we get feedback on challenges? <form action=”https://docs.google.com/a/khanacademy.org/forms/ d/1OmFRH5NoBusswiSaSYkoDiUPayycXLnpQh8IX60tJbM/formResponse” method="post" target="hidden_iframe"> Friday, October 18, 13
  • 40. Spreadsheet of user feedback pivot table! Friday, October 18, 13
  • 41. ...plus automated statistics Friday, October 18, 13
  • 42. How can we create a community? Friday, October 18, 13
  • 43. Questions & Answers Friday, October 18, 13
  • 44. 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) Friday, October 18, 13
  • 45. Spin-offs! Friday, October 18, 13
  • 46. The Hot Programs Friday, October 18, 13
  • 47. 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) Friday, October 18, 13
  • 48. Teaching Programming Online Learn Friday, October 18, 13 Practice Create Share Help