Your Daily Serving Of Points

Points on Codecademy are a great way to keep track of your progress as a learner. Currently, we keep track of the total points you have earned on the site — you can view that number in either your user badge in the header bar or on the right hand side of your profile.

In addition to tracking your long term learning goals through total points, we have added the ability to track how much material you have covered each day with daily points tracking. From now on you can see how many points you have earned today through your user badge, as well as in your profile. Your profile will also keep track of your 'daily high score' — the maximum number of points you have earned in a single day. There may even be some achievements lurking for your big days!

profile points

Announcing Python

When Zach and Ryan started Codecademy last August, they envisioned a place where anyone could come to learn how to code—in any language—to build the things they dreamed of and to use programming more effectively in their everyday lives. Since August, millions of people have used Codecademy to learn awesome front-end technologies like JavaScript, HTML, CSS, and jQuery.

Moving Server-Side—to Python!

We’ve spent the past few months working on adding more languages to Codecademy and the first one (and most requested!) launches today—Python! Python is used by hundreds of thousands of developers worldwide. Lots of schools and classes use it as a starter language because of its clean and readable syntax. Advanced developers use it at companies like Google and NASA. It goes nicely as a server-side backend to what many users have learned to do with JavaScript.

In January, we started the shift towards supporting more languages with the release of Codecademy Labs (by Amjad Masad, creator of repl.it and Codecademy team member). Labs ran Ruby and Python on the client side, allowing users to use the interpreter offline (so long as the page had been loaded) with reduced latency. Labs has been an awesome testing ground for the technologies that we’ve built, and we discovered that much of the experimentation with client-side Ruby and Python is constantly broken by updates in browsers.

Everything we’re launching today has been built from the ground up and rearchitected to run Python server-side. The infrastructure we’ve built can help us launch other server-side languages you’ve been asking for sooner than we expected.

Create Your Own!

As with all the other languages, all of our content is created by our users. Think you have what it takes to write a Python course? Create one now!

New Keyboard Shortcuts and Next Exercise's Information

Exercise Keyboard Shortcuts

Many of you have requested keyboard shortcuts to navigate between exercises in a course. As of a few days ago, you may have noticed the following revised keyboard shortcuts instructions:

Mac users:
mac keyboard shortcuts

Windows/Linux users:
windows keyboard shortcuts

Why these keys?
We chose key combinations that wouldn't conflict with existing browser actions. For example, a combination of ⌘ + N or CTRL + N already tells your browser to open up a new tab.

With our new shortcuts, you can move to the next exercise of a section by pressing ⌥ + T or ALT + T. You can also move to the previous exercise using ⌥ + P or ALT + P.

Next Exercise's Information

When you complete an exercise, you'll now see the name of the upcoming exercise.

alt text

This new change makes it a little bit easier to see your progress in the console.

Discuss these features in our forum!

Keep the streak alive

As someone who learned to code outside of the classroom, I know how important it is to establish a regular routine for applying the concepts that you're learning. The more frequently you use the concepts that you encounter on Codecademy, the more easily they'll stick.

This is why we've just added a new element to your profile: the streak. The streak is the number of consecutive days on which you've completed at least 1 exercise on the site. As long as you keep learning at least a little bit each day, you'll keep the streak alive. This way, you can look back on a long streak and feel proud that you've been leveling up your coding skills every day.

See how long you can keep the streak alive!

http://cl.ly/image/0P1p1H2C2e0s

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!

alt text

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:

Forum view for Getting to Know You, Part I - Section 1, Exercise 1

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.

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:

    1. The rgb code of the color.
    2. The hex code of the color.
    3. 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!