Review: Introduction to Systematic Program Design – Part 1 — Coursera

Some years ago I tried reading How to Design Programs (HtDP) by Felleisen et al., which is an introductory computer science text book. It focuses on a special “design recipe” for designing programs and teaches programming in a Lisp-variant. The authors claim that students who start with HtDP and then proceed to study Java for one term tend to become better Java programmers than those who have been taught Java for two terms.

The premise of the book did sound tempting. Sadly, I found that the pace was way too slow to keep my attention. How to Design Programs was tedious to read because it was rather verbose, and, for my taste, there were too many comparatively insignificant exercises. What I also didn’t like was that the authors went out of their way to avoid mathematical examples, which occasionally led to programs that were more complex than they otherwise would have been. My memory is a bit foggy, but I vaguely remember an exercise in which you had to process a list that consisted of images, but the underlying principle could just as well have been illustrated through some basic mathematical operations on a list of integers.

I eventually put HtDP on the shelf and forgot about it, but I was reminded of it again when I learnt that Prof. Gregor Kiczales of the University of British Columbia was about to teach a course based on HtDP on Coursera, called Introduction to Systematic Program Design. I signed up because I still had an interest in learning the design recipe, and was curious whether it really helped turning you into a better programmer. The original announcement promised a course that would teach you the design recipe in a special “student language”, a variant of Lisp, and once you’ve made it through that sequence, you could pick a different language to tackle the same material again, and see how the design recipe would help you to become more productive in a possibly unfamiliar language more quickly.

Coursera logo of How to Design Programs

Coursera logo of How to Design Programs

Before I go on, I should probably talk about what the design recipe is. In short, it’s a systematic approach to designing programs. There are recipes for designing functions, data definitions, and even interactive programs that use Racket. Further recipes cover, for instance, function composition, backtracking search, or generative recursion. You shouldn’t think of those recipes as straightjackets but as guides. They may be unnecessary for simple programs, but with more complex ones, they allow to reason about the problem you want to solve in a more disciplined way.

Here is the recipe for designing functions, which I’ve taken from the course site:

;; Number -> Number
;; produces n times 2
(check-expect (double 0) (* 0 2))
(check-expect (double 1) (* 1 2))
(check-expect (double 3) (* 3 2))

;(define (double n) 0) ; this is the stub

;(define (double n)    ; this is the template
;  (... n))

(define (double n)
  (* n 2))

The first line describes the involved data types. To the left are the types that constitute the input, to the right the types that will be returned by the function. The next line is the purpose, which informs the reader about the function in English. The “check-expects” are tests for the function, but before you write those, you are supposed to write the stub. With the stub, you can then run the tests and check whether they were well-formed.

The templates were recommended for beginners, and were dropped in the latter half of the course. As the name implies, they give you a template for the actual function you’re going to write. Now, in the given example, this may look a bit silly, but when you’re working on a more complex function that requires, for instance, generative recursion, the templates are quite useful. There is a bit more to the design recipe as it extends to data definitions and recommendations for function decomposition, but their general outline should now be clear.

Introduction to Systematic Program Design was originally planned as a single course, spanning 14 weeks, if I recall correctly. However, this was changed and the course split into two parts. A starting date for part 2 has not been announced yet. However, Prof. Gregor Kiczales wrote that they might offer part I again first, aimed at students at the University of British Columbia first, before hosting part II on Coursera.

The course itself targets both beginners and experienced programmers. According to Prof. Kiczales, more experienced programmers who took his course said that it helped them improve their craft. I’m in the latter camp, and I subscribe to that notion. Introduction to Systematic Program Design took me a few dozen hours to complete, but I’ve probably saved half of that amount time on various programming projects already thanks to following the design recipe at times.

The course takes eight weeks and consists of eight units. There are eight weekly quizzes, two programming projects, and one final exam. To pass the course and earn a certificate, you have to have a score of 50% for a regular certificate of accomplishment, and if you want to earn a certificate with distinction, you need 80%. Homework counts 40% of the grade, the projects 30%, and the final exam 30%. I’ll say more about grading and the projects further down.

The first few weeks of the course are relatively slow-paced. If you’ve got no experience with programming, you should pay close attention and only proceed if you really understand all the concepts that are taught. The videos offer excellent support as they not only cover the necessary theoretical foundations, but also walk you through many examples. Experienced programmers can go through the first three weeks probably rather quickly. They cover data types, function composition, and how to model data. However, the course uses a Lisp-variant as its teaching language. If you come from an imperative background, you may find some of the assignments challenging. However, each week numerous practice exercises in various degrees of difficulty were provided that enable you to smoothly work your way up from the lecture material to the homework problems.

Week 4 introduced interactive programs. I was quite surprised how easy it was to animate some geometric shapes on screen. As the programs became more complex, I was pleased by the user-friendliness of the DrRacket environment, which was a real joy to use. In week 4 there also was a noticeable increase in difficulty. It should probably be pointed out that some of the practice exercises tended to be more challenging than the homework problems, which were assessed in the quizzes. One of the exercises had you code up a rolling lambda symbol, the DrRacket logo. It was supposed to change direction when you click the mouse, or when it hit the left or right border of the screen. I’m not sure the following still image can convey it clearly, but I hope it’ll do:

Rolling lambda, moving from right to left

Rolling lambda, moving from right to left

This problem involved rotation in positive and negative direction, translation on the x-axis, collision detection, as well as user interaction due to capturing mouse inputs. I noticed that there were many complaints in the forum about that exercise. I then checked my solution with the one that was provided, and could see what the issue was: the solution the course staff provided was tersely written and needlessly complicated, and therefore difficult to follow.

However, I was pleasantly surprised that the people involved with the course reacted quickly to the, in my opinion, justified complaints and revised their sample solution. Some days later an additional practice problem was added that slightly simplified the original problem. I found this attitude most impressive. From university I am used to a “sink or swim” approach, which is a stance you can encounter in some online courses as well. For instance, in Martin Odersky’s Functional Programming Principles in Scala there was an enormous discrepancy between the material in the lectures and the exercises, but the TAs thought this was no problem at all and only reiterated that this course was basically identical to the one at EPFL, and that they had no intention of making the material more accessible. What the TAs didn’t tell you, or didn’t want to draw attention to, though, was that at universities you don’t just have lectures and hand-ins, but also tutorial sessions or “labs” and office-hours. In one of the announcements Prof. Kiczales specifically made the point that the course, when taught at UBC, has a weekly three-hour lab session, which obviously can’t be replicated online, and that as a result, the online offering may be more challenging. However, instead of UBC only putting their course material online, they did their best to provide a supportive infrastructure, without watering down the course.

That this course wasn’t “dumbed down” became clear in the second half, which covered recursion and mutually referential types, eventually leading to generative recursion. Week 8 had, fittingly, some of the most challenging exercises which asked you to write programs that generate various fractals. The final project was an application of the backtracking search that was introduced in the lectures that discussed how to solve Sudoku puzzles. The variation was to write a solver for the 4-queens problem, with the option to generalize the solution to the n-queens problem. By week 8 I saw the value of the “design recipe”. While it looks like overkill in the first few weeks, which is a point Prof. Kiczales acknowledged himself repeatedly, it does make your life easier if you stick to it.

Judging from the discussions in the forum, a vocal minority seemed either unprepared for a programming course or unwilling to forget about “object-oriented programming”, adapt the mindset of a beginner and just learn the basics of Lisp. There were threads with literally hundreds of replies in which “seasoned software architects” tried to argue that Lisp was the wrong choice for the course and that it should be taught in Java or Python instead. This was quite tragic to see since Lisp and especially the “student language” we used can be described very concisely. I wonder what would have happened if those people just had sat down with an open mind and tried to learn the few language rules of Lisp instead of making a post about how “useless” and “weird” that language was.

Lastly, a word about grading: I had the impression that there was a dramatic rate of attrition throughout the course. While the forum seemed lively during the first few weeks, activity slowed down noticeably as the course went on. Yet, I would assume that concepts like “closure” or the traversal of arbitrary-arity trees would generate more questions than, say, the problem of concatenating two strings or changing the color of a rectangle. I’d be interested to see some retention statistics. In the latter weeks, it seemed that almost exclusively people with significant previous experience were populating the forums. One guy shared personal anecdotes from meeting John McCarthy, the creator of Lisp, for instance.

There were quite a few discussions in which Prof. Kiczales contributed, too. One thread I particularly enjoyed was devoted to optimization strategies for the Sudoku solver. While I avoided the forums in the first half of the course, I saw them becoming increasingly valuable in the second half. However, if my perception is correct, then the other side of the coin is that courses like this only increase the “digital divide”. It seemed that one of the promises of MOOCs was to bring higher education to people who would otherwise not have access to it, but I have the impression that it is mostly those who are advantaged already who make use of them. This is a more philosophical issue, but one that shouldn’t be ignored. I noticed that Udacity made great strides in offering preparatory courses that try bridge the gap between high school and university-level courses, so there is hope that MOOCs may one day indeed educate the masses and not just further the education of an intellectually curious minority. Making college-level courses more accessible by providing preparatory introductory and remedial courses is a challenge for Coursera and not necessarily UBC, though, so this is in no way intended to be a criticism of Introduction to Systematic Program Design.

After this diversion, let me now make some remarks about the grading. The homework problems are not automatically graded but evaluated through quizzes. Probably peer-review may be a better solution. In their current form the homework problems may be difficult to grade automatically since the majority of the exercises was such that there was more than one possible solution. I’m not sure a satisfying solution exists for this problem. For instance, MIT’s Introduction to Computer Science and Programming on EdX split up the more elaborate assignments and had students submit their solution in multiple parts. This was a tedious process, and not only because there were plenty of instances were the autograder expected a certain approach instead while rejecting a perfectly valid alternative one.

Speaking of projects, the first project was to write a simple text editor similar to what is found on old mobile phones:

Screenshot of the editor

Screenshot of the editor

This is a neat little interactive application. The program rejects invalid input, the cursor can be freely moved around to change the insertion point, and the backspace key deletes the character to the left of the cursor if there is any.

The second project was, as I said above, a solver for the 4 queens problem, based on a backtracking search. This was a very enjoyable exercise too, and one where it quickly paid off to follow the design recipe. There was a change in grading this last exercise, though. I suspect it had at least to some degree to do with the fact that the rate of attrition has, or at least seemed to be, very high. The deadline for the project was pushed back by four week to give copious amounts of time to finish the course material and the project. However, the final project was self-assessed, meaning that in theory you could just give yourself the highest score without doing the any work and thus get 15% of the course grade for free. I found this change of the course policy unsatisfactory. On the other hand, most probably enrolled in this course to learn something and not just to weasel their way to a PDF certificate.

The final exam was worth 30%. It was designed as the equivalent to a 24-hour take-home exam. It covered material drawn from all eight weeks of the course. The exam was not particularly challenging, but this may just be testament to the high quality of the teaching. Overall, Introduction to Systematic Program Design – Part 1 was a fantastic course, and I’m eagerly awaiting the second part.

Addendum:
After I wrote this review, Prof. Kiczales announced that Introduction to Systematic Program Design – Part 1 will be offered again on the 4th of September. Changes include an increase in the duration of the course form eight to ten weeks to even out the workload, the addition of a third project, and a change in the assessment of the homework problems.

No, Java is not a good first programming language

Recently someone reached this site through the search phrase, “is java a good first language 2013”, so I felt tempted to answer this question from my own highly subjective point of view. The short answer is no, it’s not. In fact, Java is one of the worst first languages you could pick. In the following I’ll highlight two main issues. One issue, the complexity of Java, will make life more difficult for you immediately, and the other, the danger of developing myopia regarding programming languages and their capabilities, has the potential to hurt you for many years to come and possibly your entire career.

For a beginner it can be exhilarating to make a computer bend to your will. However, the path to reaching even a low level of proficiency is paved with copious amounts of frustration. Writing code demands a level of attention to detail and a degree of logical thinking that is above what the average person could muster. Gaping holes in your logic are par for the course in, say, mainstream media or normal conversations, but a computer is not so forgiving. Just learning to proceed in a clear, logical way is difficult enough for a novice. But not only do you have to learn that. In addition, Java and other “industry-strength” languages burden you with their complexity and will therefore make it more difficult for you to learn programming.

One concept you’ll learn in CS101 is what computer scientists call “types” or “data types”. The declared type indicates how a data has to be interpreted, and determines how it can be manipulated. For instance, an integer with the value 42 is not the same as a string with the value “42”, even though they look the same when printed to the screen. You can multiply an integer by 2, but not a string. On the other hand, you can append another string to a string. All of this is probably not overly exciting. In Java, you have to declare variables with their type. In a more modern language like Python, which has been around for over two decades, you simply initialize the variable since it is dynamically typed. Here is an example if this sounds confusing. [Note: Static typing isn’t necessarily bad. However, the type system of Java doesn’t buy you much, unlike the type inference in Standard ML and other functional languages, but if this is an objection you wanted to raise, then you aren’t a beginner and shouldn’t consider yourself part of the target audience of this article.]

Let’s say you’ve got a list of integers and want to double each entry of the list. If you want to use Java for that, you’ll end up writing a nice little piece of code like this:

package demo;

public class RangeDemo {

	public static void main(String[] args) {
		
		int[] myArray = { 1, 2, 3, 4, 5 };
		
		for (int i = 0; i < myArray.length; i++  ) {
			myArray[i] *= 2;
		}
		
		System.out.println(myArray);
	}
}

If you’ve never seen code before in your life, this might look quite intimidating. You’ve got all this scaffolding, and plenty of keywords which represent concepts you have not encountered yet. You know nothing about packages, or classes. The syntax is baroque. What are all those curly braces about? What are the semicolons good for?

In fact, for a beginner writing something as simple as those few lines of code can pose a significant challenge in Java. This is not because the operations that are involved are so difficult to grasp. It’s basic arithmetic, after all. Instead, the reason is that Java throws so much unnecessary complexity at you. By the way, I’ve hidden an easter egg in that code. Try to run the example for yourself, and you’ll see what I mean. Come on, try it! I’ll wait for you.

Strange, isn’t it? The console gave you an output like “[I@4b71bbc9”. This is the location of the array in memory. To actually print the content of the array, you have to import the Array class, and then convert the array to a string representation:

package demo;

import java.util.Arrays;

public class RangeDemo {

	public static void main(String[] args) {
		
		int[] myArray = { 1, 2, 3, 4, 5 };
		
		for (int i = 0; i < myArray.length; i++  ) {
			myArray[i] *= 2;
		}
		
		System.out.println(Arrays.toString(myArray));
	}
}

As you see, this is a lot of code to do something very simple. Sadly, this approach scales. While your first programs will be a few dozen lines that should be just one or two, your larger programs will be several hundred lines instead of a few dozen, and in even more unfortunate cases several thousand instead of a few hundred. At this point, you’ll have heard of “patterns”, which were developed as a consequence to the deficiencies of the language and are largely superfluous in more advanced languages. [Peter Norvig discusses this problem in greater detail in Design Patterns in Dynamic Languages, but it won’t make much sense for a beginner. Maybe bookmark the link and come back after some months or a year.]

There is also the notion of “boilerplate code”, which is a problem in Java and other equally verbose programming languages. You might think that printing “hello world” should be one or two lines. Not in Java. Or you might think that a common operation like opening a file should be a line or two and consist of specifying the file name and the mode, i.e. whether the file is supposed to be only read or read and written to. In Java this isn’t quite so simple. Here is an example I’ve taken from Hackerrank:

import java.io.*;
import java.lang.*;

public class Solution
{
    public static void main( String[] args )
    {
        File fileName = new File( "myfile.txt" );
        if( !fileName.exists() )
        {
            System.out.println( "this file doesn't exist " );
            try
            {
                fileName.createNewFile();
                FileWriter fileWrite = new FileWriter( fileName );
                BufferedWriter bufferedWriter = new BufferedWriter( fileWrite );
                //bufferedWriter.write( "write something here " );
                bufferedWriter.close();
            } catch ( IOException e )
            {
                //catch exception
            }
        }
        else
        {
            //System.out.println( "this file exists " );
            try
            {
                byte[] buffer = new byte[ 100 ];
                FileInputStream inputStream  = new FileInputStream( fileName );
                int readLines = -1;
                while( ( readLines = inputStream.read( buffer ) ) != -1 )
                {
                    //System.out.println( new String( buffer ) );
                }
                inputStream.close();
            } catch ( IOException e )
            {
                //catch exception
            }
        }
    }
}

Yes, all this just to open and read a file! Also note that the use of the “BufferedWriter” in the first try block constitutes what I’ve once been told was a “pattern”. Now if you look at the try block in the else statement, you may wonder why there is no analogue like a “BufferedReader”. In this example, the file is read as an input stream. Last time I checked, the recommendation was to use “BufferedReader” since it provided better performance when reading large files, but this is nothing you have to worry about in CS101. But let’s not get lost in details. The point I’m trying to make is that code like the one above is, well, utter madness.

By the way, this is the equivalent in Python:

#!/usr/bin/python

filename = "myfile.txt"
with open( filename ) as f:
    # file read can happen here
    # print "file exists"
    print f.readlines()

with open( filename, "w") as f:
    # print "file write happening here"
    f.write("write something here ")

Again, the example has been taken from Hackerrank. The pound sign (#) indicates a comment and is not necessarily for program execution. Thus, you’re looking at a total of five relevant lines of source code. Yes, five.

Those were just two random examples, but they hopefully illustrate why choosing Java as a first language is a rather bad idea. I’m proficient to various degrees in about half a dozen languages. However, I don’t think I’ve ever found myself in a situation where I was writing code in, say, Python or Erlang and said to myself, “I wish I could do this in Java instead.” When I have to work in Java, though, I tend to feel reminded of the increased expressiveness of other programming languages.

Instead of Java as a first language, I’d recommend you learn Python instead. Python code can be very clean and readable, and dynamic typing makes it more fun, too. I haven’t given you the equivalent of the very first Java example yet, which was doubling the numbers of an array of integers. The Java code at the beginning of this article can be expressed in Python like this:

my_array = [1, 2, 3, 4, 5]
my_array = [ number * 2 for number in my_array ]
print my_array

If this is too verbose, you can shorten it a bit:

print [ number * 2 for number in [1, 2, 3, 4, 5] ]

This is what people mean when they say that one line of Python can replace ten lines of Java. As a beginner, you’ll probably find this code easy to understand, even if you’ve never seen code in your life.

Apart from all the unnecessary complexity Java throws at you, there is another aspect I’d like to highlight: programming language myopia. Many people find it very difficult to liberate themselves from the mental models and habits they have acquired in their first programming course. Instead of adopting a beginner mindset again when picking up a different language and learning what it offers, they view everything from the one perspective they know, and happily write Java in Scala or Java in Python or Java in any other language that lets them get away with it. They pronounce that differences between programming languages are “just syntax” and never realize that they don’t make use of more advanced features of the languages they use.

It’s too easy to be complacent when your code seemingly works. Your overly verbose Java in Scala does the job, so why would you bother stretching yourself a little bit? This attitude is common, and you’ll have no problem bumping into people who reject using more powerful languages because of their “weird syntax”. For more on this, read what Paul Graham has to say about Blub programmers. It may come in handy at a nerdy cocktail party. Variations of what Paul Graham calls the Blub Paradox can happen at all levels of competency. People think what they are doing is good enough and don’t make an additional effort. However, it is a missed opportunity if you view a more expressive language from the view of a less expressive one and never familiarize yourself with the possibilities more powerful languages offer.

For a possibly surprising example, let me tell you about one of the MOOCs I sampled earlier this year, MIT’s Introduction to Computer Science and Programming. There are many conveniences in Python, for instance an immediate variable swap. Swapping the content of the variables a and b requires nothing more than writing “a, b = b, a”. On the other hand, in Java and many other programming languages you would have to use a temporary variable and express the same in three lines. Of course, you can write the same three lines in Python and use the temporary variable you’re used to. It works, but it’s considerably less elegant. This is a relatively harmless example. More severe was the introduction to object-oriented programming in that course was taught from a clearly Java-inspired perspective. In Java it is necessary to write so-called getter and setter methods, sometimes called accessor and mutator methods. Yet, this is superfluous in Python, where you have direct access to attributes you want to access or modify. Now, if this happened in a CS course that was taught by MIT, then it’s probably safe to assume that a college freshman who is starting out with Java isn’t immune from that kind of programming language myopia either, so do yourself a favor and learn one or two other programming languages first.

Review: CS201: Elementary Data Structures — Saylor Foundation

Saylor’s CS201: Elementary Data Structures follows their three-course introduction to programming sequence. The course is a standard data structures course, covering arrays, stacks, queues, graphs, and hash tables, and their implementation. As in previous courses, some segments were taught comparatively. For instance, implementations of a stack were shown in C, C++, and Java. This is a nice touch, although those languages are a bit too similar to lead to interesting insights.

I don’t think the C-family of languages is particularly suited to teaching data structures and algorithms to beginners, though, since they introduce a fair amount of “accidental difficulty” that is due to the syntactic complexity of those languages and not the subject. As a consequence, two of the eight units dealt with pointers and references in C++, and dynamic memory allocation, respectively.

Apart from data structures, an intro to the analysis of algorithms (big O) was provided, which was subsequently applied to a number of searching and sorting algorithms. A prominent omission among the sorting algorithms was quicksort, though.

Overall, this course is a great complement to the many introductory programming/CS intro courses that are available online. I just checked the EdX, Udactiy, and Coursera catalogues, and there is still no dedicated course on data structures available. This means that for the time being, Saylor’s offering fills a void.

My only criticism relates to the final exam. Saylor continually improves their courses, and is very receptive to feedback, so there is a good chance that the few mistakes I spotted will be corrected soon. I don’t want to discuss specific exam questions, but to give you one example: one question asks you to identify a sorting algorithm that is unsuitable for large arrays. However, they all exhibit quadratic runtime and thus were all unfit. Yet, the answer choice “none” was seen as wrong. The expected answer was presumably that bubble sort was unsuitable for that task, but I don’t want to select an answer choice that conflicts with reality just because the examiner (or grading script) might expect it. Some other questions were on C++ syntax, which I found questionable in the context of data structures. This wasn’t a big issue, but it surprised me nonetheless. Thus, I think that it would be helpful if Saylor either offered a sample exam, or expanded their list of learning outcomes to reflect the content of the exam as well.

[Addendum: I emailed Tanner Huggins at Saylor Foundations who quickly replied to me, saying that he addressed the issues I’ve brought up. He also wrote that Saylor courses eventually go through a peer-review process, where feedback on courses and exams is solicited from qualified faculty members, and that Elementary Data Structures hasn’t gone through this process yet.]

Review: An Introduction to Interactive Programming in Python — Coursera

I just finished An Introduction to Interactive Programming in Python on Coursera, which is taught by Rice University professors Joe Warren, John Greiner, Stephen Wong, and Scott Rixner. This course has the rather unique approach of teaching programming by building games of increasing complexity, instead of teaching programming language syntax with a plethora of dull exercises. Overall, it was an excellent experience, and thoroughly enjoyable. Most of all, it was great fun.

I originally signed up because I was interested in the structure of the course. I liked the whimsical style of the instructors, and before I knew it, I was sinking a couple hours a week into programming games. Games were only used as a vehicle to teach programming, though. I think this is a much more attractive approach than coding a dreary CRUD application. Presumably, more students would stick with computer science or mere programming if they were presented with more interesting application domains. I certainly have never heard of teenagers who learned programming on their own because they wanted to write a CRUD app in Java. Games, on the other hand…

Pedagogically, the class was excellent, since it focusses on practical examples first. For a beginner, this is surely much more helpful than the misguided attempt of introducing rigorous definitions for their own sake. The content was similar to a typical introductory programming class that is taught using Python, such as MITx’s 6.00 or Udacity’s CS101. Yes, object orientation is  covered, and so are common data structures like lists, sets, dictionaries and tuples. Even more advanced concepts like list comprehension were taught.

As teaching platform an online IDE named Code Skulptor was used, which implements a subset of Python 2.6 in JavaScript. Two bundled multimedia libraries make it much easier to write games. Code Skulptor provides syntax highlighting and code folding, i.e. the ability to hide the definition of a function. This environment worked very well for most of the course. The last few assignments led to code bases in excess of 200 lines, which made programming in the browser a bit awkward, though.

Now, let’s talk about the games you’ll write in the course: the first project is an implementation of rock, paper, scissors, lizard, Spock, which uses console output. The week 2 project is not much more complicated: it’s the guessing game. You know, guess a number between 1 and 1000. This project also served as a vehicle to introduce binary search, and basics of GUI interactivity. Week 3 was only a minor step up, covering modulo arithmetic by programming a stop watch, and implementing a “game” on top of that: try to stop the counter at the start of a second. Since the counter keeps track of 100 ms segments, this is rather difficult.

The fun started in week 4, though, which focussed on Pong, using simple vector graphics. Pong may not be very exciting nowadays, but it’s quite satisfying to play a round or two (against yourself) once you’ve implemented all game mechanics. It felt satisfying just seeing the ball physics in action. Quite a few students seemed to have struggled in week 5 with the implementation of Memory, as it involved more complex game state and manipulations. In Pong everything is visible all the time, while in Memory cards aren’t always exposed. As you can see from those examples, the assignments got progressively more complex, and they required increasing sophistication.

The most time-consuming project was probably Blackjack, the week 6 project, which implemented a simplified rule set of that game. The addition was to work with tile maps. The last two weeks tied everything together with an implementation of Asteroids: game physics, sound, tile maps, collisions, game state, it’s all in there. Despite being the most elaborate project, it was very straight-forward. As such, it was a rewarding conclusion to this course. Here’s a screenshot:

RiceRocks

RiceRocks: An implementation of Asteroids

The support structure of this course was excellent, too. You could even email a help desk at Rice University if needed, and each week, a support thread was started in the forum that discussed the most common stumbling blocks. Examples of programming concepts were plentiful, and supplementary exercises helped reinforce concepts, if you needed it. I didn’t have to resort to any of those resources, but knowing that they were there was reassuring. I also appreciated that materials were posted early, on Saturdays, which gave you a head start, and made it much easier for me to find the time for this course.

There were only a few blemishes. One quibble I had was that in one of the later projects some “Java in Python” was taught as students were asked to write a “getter” method. However, in Python you can just access the attributes directly. Peer review of the weekly assignments worked well. However, the grading rubrics focussed merely on the exhibited functionality of the programs, not on the actual code. I found this questionable since it may reinforce bad habits. A grading rubric for “style” may be a reasonable addition to future iterations of this course.

To summarize, An Introduction to Interactive Programming in Python is a great way for a beginner to get started with programming. This course is also interesting for more experienced programmers, since you’ll be implementing simple games. I certainly found this enjoyable. Granted, it probably won’t provide much of a challenge if you’ve made it through an introductory programming course already, but it should be quite entertaining.

Review: CS107: C++ Programming — Saylor Foundation

There are a few MOOCs I’m interested in taking that are taught using C++. I’m not overly familiar with this language, which was motivation enough for me to go through the third course in Saylor’s Computer Science curriculum, CS107: C++ Programming. That course promises a thorough introduction to C++ programming. It is not a course for beginners, though. You are expected to have a basic familiarity with programming, including object-orientation.

CS107 has been my third course on Saylor, and so far this is the course that best illustrates the viability of their approach to teaching. Yes, all the material they use is freely available elsewhere. However, by curating content and offering a syllabus, Saylor provides a helpful structure for self-learners. This makes it easy to follow along, and greatly increases the value of the original sources. For instance, Google’s C++ class is too dense and fast-paced for anyone who isn’t an experienced programmer already, and Keith Schwartz’s Stanford hand-outs might not be overly useful without the accompanying lectures, which are missing. An older version of Stanford’s CS106B is available online, though. Further, the tutorial on cplusplus.com provides very little hand-holding, with very few examples and no exercises at all. Saylor solves all those problems by combining those and other resources.

I would recommend that you get a book to complement the material. While I do think that CS107 is a perfectly adequate university-level course, it can be quite convenient to be able to quickly look-up topics in just one place, instead of having to go through various links and sites. There are a few free sources available. I’ve used Allen B. Downey’s How To Think Like a Computer Scientist: C++ Version. It has served me well as a concise reference, even though it won’t help you much in the second half of the course, which explores more advanced topics such as templates, preprocessor directives or manual memory management. Speaking of supplementary books, Eric Roberts offers a draft of Data Abstractions in C++ free of charge. It is quite verbose, but the book looked good to me. You might appreciate the many exercises it offers.

The final exam was quite satisfying, apart from some minor issues. The majority of questions were of a practical nature, which I find laudable. The most common question type was based on tracing the execution of a program and choosing the correct output from a number of alternatives. Other questions covered language details which, for the most part, were perfectly reasonable. I found just two of the 50 questions hard to justify. One asked to evaluate a statement of the form “x = (y = 10, y + 1)”. This is syntactically legal, and does evaluate to an integer, provided both x and y have previously been declared. However, I couldn’t think of a case where you would want to write code like that. Some other question presented you with a program that reads in a file consisting of a short sequence of characters as binary, and print the content character by character as hexadecimal values. I would have been fine with a short program or a question that tests whether you can manually convert from one number system to another, but seeing instructions that say, “(Hint: you should compile the code to figure it out.)” caught me off guard, and not just because I was doing this exam on a computer on which I didn’t have any software development tools installed.

What I disliked, though, was that all code fragments were presented as unformatted code. It is quite startling how difficult it can be to read code that wasn’t properly indented. Saylor should fix this issue, and it should be a relatively easy fix too. Despite the few minor flaws, though, I think that CS107 is a solid course. It won’t turn you into a master C++ programmer, but afterwards you should know enough C++ to go through more advanced CS courses that are taught in this language.

[EDIT: On 17 June I received an email from Tanner Huggins, Content Development Associate at Saylor Foundation. He let me know that they’ve fixed the formatting issues with the exam I had pointed out.]