This document discusses teaching programming online using Khan Academy's approach. It outlines how Khan Academy teaches programming through interactive tutorials called "talk-throughs" where students write code along with video instructions. Students are assessed through coding challenges that can be solved in multiple ways and are meant to be fun. Challenges are automatically graded by testing the student's code against example solutions. A community is built through a question and answer forum. The document also discusses potential programming languages and topics to teach as well as techniques for gathering student feedback.
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
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
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
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
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
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