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.

    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.

    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!

    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.

    We're launching this in the beta phase to a small group of course creators first. If you'd like to be part of this group of beta testers, please get in touch with contact@codecademy.com. In your email, please include the link to your course and either the username or email you use on Codecademy.

    Here's a sneak peek of the "add collaborators" interface:

    alt text

    There is an interesting paradox in teaching: the better you know a subject, the harder it is to talk to beginners. Experience means you have forgotten what tripped you up when you were a beginner.

    Consider typing. Or division. Or even reading this sentence. Easy now, right? Looking back, it's hard to remember why they were hard. Looking back, the stumbling blocks are invisible.

    Let's consider a sophisticated concept you know and love: variables.

    Variables are so fundamental that it is impossible to write useful code without them. I bet you think about them about as much as you think about breathing. But they weren't always that easy. Consider the following code:

    >>> myValue = 5
    5
    >>> myValue + 3
    8
    >>> myValue
    

    What will this third command print? The answer is 5, but many beginners will say "8."

    Why? Most misconceptions are the brain enthusiastically applying previous knowledge to new situations. If you can figure out what rules and knowledge your students are bringing to the table, you can start to anticipate their misconceptions and design lessons and error messages accordingly.

    For example, in basic arithmetic, adding two numbers yields a third number. It is not at all obvious to students that addition does not come bundled with assignment. And from your perspective this is an invisible stumbling block, because this is knowledge you know so well you didn't even remember it was there to be learned.

    Before we go on, take a moment to write down everything you know about variables, or know how to do with variables. Try to state the "obvious."

    Nice! Now check your list against this one and see if there are any invisible stumbling blocks missing from your list. (The specific bullet points will, of course, depend on the programming language you have in mind, but the purpose of this list is to help you spot invisible concepts.)

    • why they are so hugely important for writing software
    • how to change the value of a variable
    • how to perform operations on a variable without changing its value
    • how to check the value of a variable, both on the interpreter and in a script (crucial for debugging)
    • variables can store any data type, including strings, objects, and in some languages, functions
    • variables can refer to other variables
    • multiple variables can point to the same thing
    • variables can have no value, or an undefined value, and this is different from a value of '0' or ""
    • changing the name, and even capitalization, means a totally different variable to the interpreter.

    Want more practice? Try unpacking some other "obvious" concepts, like printing (with a printer, right?), strings (let's make a sweater), and functions (this is a hard one—make sure to practice on a real human).

    Crucially important note: this does not mean that you should try to explain all of these things to a beginner, but it is very important to remember that they exist so you don't blithely run your students over rough terrain.

    So how can you help students around these stumbling blocks?

    1) State the "obvious." It's only obvious once you already know it.

    2) Plan to spend 2x-4x more time on the basics than you think students will need. Regardless of the elegance of the explanation, students need time to wrap their heads around new concepts.

    3) Iterate on feedback. Put your lesson in front of students and ask them to think out loud as they take it. Asking probing questions will help you uncover their misconceptions, but don't jump in with explanations. Tweak your lessons, then rinse and repeat.

    Share your thoughts and collaborate with other teachers and course creators in our course creator forum.

    Thanks to E.O. Stinson and Kyle Conroy for their insightful draft feedback.

    Today we're rolling out an improved look and experience for tracks.

    Tracks are series of courses grouped to help you master a topic or language. We first introduced them a few weeks ago, following the release of our first HTML and CSS courses. Since then, we've listened closely to your feedback and cooked up a little design upgrade to make tracks even easier to use.

    <img src="http://dl.dropbox.com/u/77358750/Blog/2012-05-03%20Tracks%20Announcement/new_tracks.png" alt="New tracks screenshots">

    Here are a few of the key changes:

    • View all the courses in a track at once, rather than drilling down into units
    • Clearer visuals for different course types (projects, challenges) and progress
    • More focus on guided content—the "Learn" tab now lists all tracks

    We hope these design changes make it easier to overview your progress, work through tracks, and most of all—get you learning to code!

    Check out the new tracks! »

    JavaScript is one of the fundamental programming languages of the internet. It serves as a great introduction to general programming principles, and it shows the power of programming.

    Yet, as important as Javascript is, you need to know more than Javascript to create a website. For web development, HTML and CSS are as important as JavaScript is. Since one of the most frequently requested tutorials on Codecademy is one around how to actually create a website, we're launching a new set of courses on HTML/CSS. Best of all, with these courses, you can see what your code is doing in one click. It's the best of learning by doing - write your code out and see what happens instantly!

    I learned to write HTML and CSS this way, and we hope that our new tutorials let you learn the same way. We're starting slow - you'll be building a basic webpage. After that, you'll learn how to use JavaScript to spruce up webpages and to create your own personal homepage. Join us!

    Codecademy has always been the easiest way to learn to code. Today, we're becoming much more - we'll also be the easiest way to teach programming.
    The past few months, our team has focused on building great content for our users - we've pushed out new courses every week since the beginning of 2012 with Code Year, and we've added awesome new features. Some of them we haven't even announced yet! Those of you that have been watching the site closely have probably noticed we changed the editor - we're now showing you where your errors are occurring (you'll see a little "x" next to them). We've also redesigned our interface to show you lessons, projects, and challenges, a new organization framework we've developed and will explain in more detail now.

    Today, anyone can create their own Codecademy lesson. We're also expanding beyond JavaScript - lessons can be created in Ruby or Python too! The lessons are just as interactive and exciting as the ones that Codecademy itself has created. We'll be featuring the best lessons prominently on the site as well.

    This is part of our mission to teach the world to code. We're excited for everyone to join us in this mission by creating awesome tutorials for anyone to learn to code.

    Check out more coverage from the Wall Street Journal, TechCrunch, GigaOM, and VentureBeat.

    We’ve been blown away by the response to Code Year, our latest initiative. In less than 7 days, more than 300,000 people pledged to learn to code in 2012 (you can still sign up!). We were thinking about how to further spread the word about coding literacy when Aneesh Chopra, the CTO of the United States, called last week with an interesting proposal. We thought the proposal was in line with what we’re trying to achieve here at Codecademy so we agreed to partner up!

    Today, we’re proud to announce that we will be working with the White House to get more kids and adults learning to code. With their Summer Jobs+ program, the White House has been working on finding jobs for hundreds of thousands of people over the summer. We think learning to code is an integral part of finding a job in the 21st century economy, so we’ll be helping out by rolling out a course called Code Summer+. This will be a shorter course than Code Year that aims to teach people the basics of programming. You can find a bit more on the White House’s blog.

    More importantly, we’re pleased to announce that we’re moving Codecademy from being a strictly online learning platform to something you can do offline as well. Users all around the country and the world are getting together to talk about Code Year and to support each other as they learn. We’ve seen them get together in New York and elsewhere. Today, we’re launching meetups for Code Year and Codecademy participants worldwide. Anyone can sign up to host their own meetup or to attend another one at codeyear.com/meetups. You can meet weekly to discuss each Code Year lesson or whenever you’d like. We’re asking for companies to get involved by hosting meetups or creating Codecademy lessons by emailing us at contact@codecademy.com.

    All of this wouldn’t be possible without the help of some awesome partners. Today, we’re pleased to announce that Code Year is now endorsed by the Kauffman Foundation, Startup Weekend, Launchpad LA (hosting LA Codecademy meetups!), AngelPad, Teens in Tech, Ladies Learning to Code (in Canada), Women Who Code, Quanta (an accelerator in Kosovo), Open Network Lab (an accelerator in Japan). Companies like Foursquare, Sailthru, Skillshare, and Twilio have signed on to support our effort to get the world to code as well. We’re working with dozens more partners not included in this post (but who will be included in a forthcoming site just for partners). If you’re interested in helping out, please email contact@codecademy.com.

    We’re constantly trying to improve Codecademy for all of our users. This week, we launched new Q&A forums as well - if you look at any lesson on the site, you’ll notice you can click “Q&A” to ask questions and get answers from fellow users. We're grateful for all the user feedback and we're working as hard as we can to deliver a good experience for you all.

    Thanks for using Codecademy!

    Monday was not only the first day of Code Year, but it was a great day for the Codecademy team. We are super happy to welcome Allison House to the team as our Lead Designer.

    We had been looking for a designer for a few months - Ryan and I really place a premium on design and we hadn't quite found someone we thought could help to shape the company's design thinking. We had interviewed dozens of designers when we saw the subject line "Hey Zach and Ryan! Let's talk design" pop in our inboxes. We read into it and discovered that Allison was incredibly talented, well regarded in the industry, and passionate about education.

    After a quick Skype, we had a great feeling about Allison. We flew her out to New York for a few days and she proved to be even better in person. We spent a few days redesigning a few aspects of the Codecademy site. Allison's work spoke for itself - she's amazingly talented and will bring a whole slew of awesome new ideas to Codecademy.

    The best part though, was hanging out when we weren't working. Ryan, Allison, and I spent an afternoon exploring downtown Manhattan and walked over the Williamsburg bridge to spend some time in Brooklyn. We ended up at the Standard Hotel dancing at 2am (and Ryan and I don't even dance…).

    We're thrilled to be able to work with Allison on a daily basis. You'll see her work appearing on the site immediately. Want to come work with us? Check out our jobs page.

The official blog of Codecademy

The easiest way to learn to code

Stay up to date

Never miss a new feature and always know about scheduled maintenance

Subscribe to our feed

Sign in