Archives for : June2012

Profile Update

Many of you use your Codecademy profiles for a range of purposes, from sharing progress with friends to interviewing for jobs. Learning a new subject takes a lot of time and effort and it’s very important to us that your accomplishments stand out and shine.

We’ve reworked user profiles to give more equal weight to teaching and learning accomplishments. We’re also experimenting with ways for learners to share and compete with each other; adding your recent activity and representing your progress in a track-centric way are steps in that direction.

Hope you enjoy it, and happy coding!

Screen%20Shot%202012-06-24%20at%206.16.35%20PM.png1023x537

Q&A Forums

In addition to improving course quality and the course creation process, we’ve been busy working to improve the community experience on Codecademy. Forums have provided a resource that supplements course content and allows users to both learn from and interact with each other. Today, we’re rolling out a Q&A redesign that makes it easier to find the content and answers you need.

Instead of a general forum for each section, questions are now categorized by course, section, and exercise. Here’s an example of what the main view for navigating forum questions looks like:

Screen%20Shot%202012-06-14%20at%205.34.30%20PM.png1054x630

We’ve built the new Q&A using backbone.js and HTML5 pushState, which makes for quick navigation through the forums, and we’ve also made the system more flexible in preparation for future growth (we’re also working on more general Q&A beyond course content). At the same time, we are adopting new community norms for Q&A that will make them a more helpful, pleasant place to get questions answered and go beyond the lessons. Be sure to check out the new forums for your courses and send us your feedback!

Investors++: gearing up for a new Codecademy

When Ryan and I started building Codecademy in August of 2011, we were focused on building something for ourselves. I was teaching myself to code and was incredibly frustrated by what I found in books, videos, and elsewhere online. Ryan, meanwhile, had taught hundreds of students while we were at Columbia and wanted to find a way to teach millions more. What started as something built for the two of us has become so much more in the nine months afterwards.

Shortly after we launched, hundreds of thousands of people around the world used Codecademy. Since then, we’ve heard awesome stories from thousands of them. Some of them are below:

Ben Roberts from Memphis, TN told us about how learning just the basics of JavaScript helped him land a position as a Data Management Specialist – and that knowing the core programming concepts has been been very handy in his new job.
Juliet Waters, a writer from Montreal, has been learning programming with Codecademy with her 11 year old son, Ben, and blogging about their experiences. She told us that six months ago, she didn’t know what a programmer really did. Now she’s joined a hacker space, hosted coding meet ups, and made her own website and app! Users like Adam Travers from Bristol, UK have also shared with us how valuable it can be to combine a little coding with an existing skill. Adam is an illustrator and designer, but has found that learning some programming has greatly complemented his existing skills. He now incorporates his illustrations into dynamic websites that he creates himself!

Learning is a complex process, and we’ve put a lot of thought into designing the best learning experience possible. Many of us taught programming before Codecademy and we took what we learned there from our teaching experiences and put it all into Codecademy. That’s why we’re so passionate about learning by doing, creating, and building real projects with new technologies.

Along the way, we’ve been fortunate enough to work with amazing people as both friends, mentors, and investors. In November 2011, we started working with Andy Weissman and the folks at Union Square Ventures. They and our other awesome first-round investors contributed tremendously to both our vision and our progress.

In January, we launched Code Year as a way to show the world just how important programming is. Months later, hundreds of thousands people are getting programming lessons sent to them each week. A few weeks after we launched Code Year, we met Neil Rimer and Saul Klein of Index Ventures. Saul told us, about the world he wanted for his kids – one where code was a foreign language as important as Chinese and English for people to learn. Mary Meeker of Kleiner Perkins visited our office around the same time and painted a picture of a few industries that needed to be shaken up – education chief among them (see her 2012 Internet Trends presentation here). We spent a lot of time talking to Saul and Mary, and Mike Abbott at Kleiner about the future of education, programming, and our workforces.

Ryan, the rest of the Codecademy team and I have thought endlessly about the future of education and how we get there. It became clear that we needed partners who both understood the importance of a global company (more than 50% of Codecademy’s users are outside of the US) and the process of scaling a company far beyond the nine people we have grown to now. Index Ventures and Kleiner Perkins are joining the Codecademy family with $10 million in our second round of financing. They’re joined as well by Union Square Ventures, Yuri Milner and Richard Branson. It’s inspiring to work with both great firms and terrific entrepreneurs like Richard and Yuri.

With this new funding, we’re going to keep doing what we’ve been doing. We’ve reached millions of students in more than one hundred countries. Tens of thousands of teachers that have created Codecademy courses are now able to spread their knowledge all over the world. We want to make that process better for our students and for our teachers.

Codecademy is a global movement. We’ve hired people from all over the world – Jordan, Finland, Australia, and elsewhere – and we want anyone, anywhere to have access to an education that can change their lives.

Rarely is there an opportunity to have so much of an impact on so many people, and we’re excited to keep working for our students and our teachers. If you think you can help, come join the team.

Best Practices for Course Creation

This guest post is from Eric Weinstein, a proud Codecademy user and talented course creator. Eric learned Javascript through Codecademy and dabbled in Python on the side. He has since created and edited a number of courses across numerous tracks. In this post, Eric shares his thoughts and process on how to get started creating quality courses.

Teaching is hard. The first time I sat down in front of a room full of undergraduates and found myself tasked with communicating information to them, realizing I was largely responsible for their ability to understand the material, I was a little overwhelmed. How do you distill an entire discipline into a sequence of lectures, exercises, and discussions?

Writing courses for Codecademy is very much like teaching a class. You have to figure out the best way to explain technical terms and concepts, the best order in which to present information, and how best to divide the work into digestible pieces—exercises, sections, and courses. When writing my own Codecademy courses, I usually go about it in five steps.

1. Big-picture planning

Teaching a programming language is similar to teaching a natural language like German or Mandarin. The early exercises shouldn’t assume any special knowledge, and later exercises should build on previous ones and give students the opportunity to use what they’ve learned.

I’ve found that it’s tremendously helpful to understand the “big picture” aspect of each course that I write—what material to cover, useful analogies and comparisons, and so on. Beyond that, though, I make a conscious effort to explain to students what a programming language is good for and what they’ll be learning in the future, both to keep them informed as well as motivated.

When writing your own courses, set yourself up with a word processor, pencil & paper, or dry erase board and map out the subject you want to teach. Resist the urge to teach too much too quickly! There can always be more exercises to expand and expound.

2. Small-picture planning

Once I know what topic I want to cover, I divide the course into sections and the sections into exercises. (I usually set up the outline of my course first, then fill in the content later). With practice, you’ll get a sense of scope: how much material to cover at which level. A lesson with 100 exercises covers too much; a lesson with 3 exercises, too little. The sweet spot seems to be five to seven sections, fifteen to thirty-five exercises.

3. Exercise and default code creation

Once my outline is complete and I’m comfortable with the amount of information and the order in which I’m presenting it, I start writing exercises, one at a time. I don’t always go in order (see #5), but I do my best to ensure that I don’t introduce anything new without thoroughly explaining it. If I mention something I’ve covered in a previous lesson, I try to link back to it or provide a reminder in the hint.

I don’t usually worry about SCT (Submissions Correctness Test) creation at this point—my concern is writing readable instructions and good default code.

4. SCT building

This is the part I spend the most time on. A Codecademy lesson is only as good as its weakest SCT, and it’s very easy to write overly simple (or even broken!) SCTs if you’re not careful. The best SCTs identify the correct answer, rule out any incorrect answers, and provide useful error messages for common mistakes. For example, let’s say you want a student studying Python to write

p = ‘spam'[1]
print p

in the editor. Your SCT could just be return codecademy_lib.printed(‘p’), but this won’t check to make sure the student actually accessed the second letter of the string by offset; they might have just put print ‘p’ in the editor and called it a day. A more robust SCT would be:

if type(error) == IndexError: print “Oops! You went too far. Use a smaller number in []!” return False
elif not codecademy_lib.printed(‘p’): print “Looks like you didn’t get ‘p’! Did you start counting with 0?” return False
else: return codecademy_lib.printed(‘p’) and ‘[‘ in code

This makes sure that the student didn’t cheat by just printing “p,” while also providing helpful error messages along the way.

I always go through my SCTs as part of my overall run-through (see #5) to make sure I haven’t updated code or instructions without also updating the SCT.

5. Overall run-through

Finally, I run through my course in preview mode, exercise-by-exercise, and then in overall view mode in order to ensure that:

I haven’t introduced any information out of order;
I haven’t updated code without also updating comments, hints, SCTs, and instructional text (the most common error I run into is changing variable names in one place and not everywhere else);
I haven’t written a broken or inaccurate SCT.

If I can run through my entire course twice, providing correct and incorrect answers, without hitting a bug, typo, or inconsistency, I submit the course for review.

And that’s it! I hope some of this was helpful to you—I know it’s been a bit of a learning process for me. Good luck with your course creation, and happy coding!

Please note that a guest post is from a member of the community and not the Codecademy staff.

Preview Mode

In light of the recent efforts to enhance our course creation experience we’ve added a new feature called Preview Mode.

Before, both course creators and students would see the same functionality when previewing an exercise. This made it difficult to catch submission test errors and generally debug courses.

To make debugging easier, the new Preview Mode adds a retractable console to show helpful messages and error logs. The console will show the following:

Errors in the submission correctness test (SCT).
Errors in the student code.
Helpful debugging messages and warnings.

Now that we distinguish between preview and student modes, we define different behaviors for our teachers and students:

Erroneous SCTs will pass in student view (so our students don’t get blocked).
Erroneous SCTs will fail with a console message in preview mode.
Preview Mode will always show up-to-date default code in the editors unless chosen otherwise.

Want to learn more? Read the official documentation here.

Screen%20Shot%202012-06-10%20at%205.31.55%20AM.png1184x438

The jquery.expect Library

Improving course creator SCT

Since the launch of the Codecademy course creator tool, we’ve been so lucky to have such smart and dedicated people writing and maintaining courses for our platform. In that short period, in addition to our own experience with the tool, we have received a lot of feedback from course creators about the major pain points of creating and testing a course. So lately we have been iterating and shipping small features and many fixes to the course creator. However, there is one point we haven’t really addressed — how hard it is to check the correctness of the student submitted code, especially in the “Web” courses.

Course creators have to write tests, Submission Correctness Tests (SCT), that would run against the students’ submitted HTML, CSS and JavaScript after they’ve been processed and rendered in an in-browser iframe. The only convenience we gave our beloved creators was the fact that we loaded jQuery for them. However, they had to pretty much do all of the heavy lifting.

The old submission correctness test is wrapped with a function that, when called, expects one of the following return values:

true: Test has passed.
false: Test has failed with an unknown error.
Error string: Test has failed with an error message to show to the student.

Example from one of our recent Web courses:

if ($(‘div’).length === 0) { return ‘Did you add a new div to your page?’;
}

if($(‘div.post’).length === 0) { return ‘Make sure your new div has a class name of “post”!’;
}

if ($(‘div.post > h2’).length === 0 || $(‘div.post > p’).length !== 2) { return “Your div should surround the h2 and two p’s”;
}

// Regexp to match color in hex and rgb.
var rColor = /ccc|rgb\s*(204,\s*204,\s*204\s*)/i;
if ($(‘div.post’).css(‘border-bottom-style’).match(/dashed/) == null || $(‘div.post’).css(‘border-left-style’).match(/dashed/) == null || $(‘div.post’).css(‘border-left-color’).match(rColor) == null) { return “Make sure you give your post div a border.”;
}

if($(‘#nav li’).css(‘padding-top’) !== ‘5px’ && $(‘#nav li’).css(‘padding-left’) !== ‘5px’) { return “Give your nav elements proper padding!”;
}
return true;

Here are the major pain points and what we can do to make them better:

Expressiveness: An SCT is very verbose and there are repetitions in the code.
Browser differences and incompatibilities: Even though jQuery greatly helps normalize browser differences, there are many things that it just doesn’t help with. For example, when trying to get an element’s color using $().css(‘color’) you may get one of the following three formats:
The rgb code of the color.
The hex code of the color.
The English name of the color (if you originally specified it using the name).

Another noticeable issue in the previous example is that checking the border or the padding, using the shorthand notation, isn’t possible because most browsers would return an empty string if you try to get $().css('border') or $().css('padding'). In order to check those CSS rules, you would have to specify and check each direction and style.

Readability: An SCT is hard to read, understand, and maintain across all of the browsers that we support.

Enter jquery.expect

jquery.expect or $expect is a simple DOM assertion library built on top of jQuery and is inspired by LearnBoost’s excellent expect.js library.

Without further ado let’s rewrite the previous example in $expect:

$expect(‘div’).to.exist(‘Did you add a new div to your page?’);

var missingPorHMsg = “Your div should surround the h2 and two p’s”;
$expect(‘div.post’).to.exist(‘Make sure your new div has a class name of “post”!’) .and.to.have.children(‘h2’, missingPorHMsg) .and.to.have.children(‘p’, missingPorHMsg) .that.has.elements(4, missingPorHMsg).end() .and.to.have.css( ‘border’ , ‘1px dashed #ccc’ , “Make sure you give your post div a border!”);

$expect(‘#nav li’).css(‘padding’, ‘5px’, “Give your nav elements proper padding!”);

Thus, we have transformed a very verbose and unreadable test into a succinct and elegant one. $expect is very fluent and expressive and we think it would immensely help in writing SCTs and assertions in general.

$expect has many other features that you can find in the documentation. One new feature is event testing, which was impossible with the old framework.

$expect(‘button’).to.click(function () { $expect(‘div’).to.be.hidden();
});
$(‘button’).click();

The new $expect library is well tested and stable. Nonetheless, jquery.expect is still in the early development stages and your feedback is greatly appreciated.

We think other people and projects may benefit from a library like jquery.expect, so we have made it available on Codecademy’s github under the MIT license. Happy testing!

Course Collaboration: Beta Release

Codecademy isn’t just a place for people to learn to code. It’s also a platform for people to create courses and share their knowledge with all of our users. As such, we’re focused on making it as easy as possible to create high quality courses.

This is why we’re starting to roll out a new feature for course creation: course collaboration. Soon, course creators will be able to invite collaborators to work on their courses with them. These collaborators will have full course editing powers, but only the original course creator will be able to add and remove collaborators.

Here’s a sneak peek of the “add collaborators” interface:

Screen%20Shot%202012-06-07%20at%204.01.50%20PM.png1103x387