Combating the Code Warrior :
A Different Sort of Programming Instruction

Debora Weber-Wulff

Technische Fachhochschule Berlin

FB Informatik

Luxemburger Str. 10

13353 Berlin, Germany

weberwu@tfh-berlin.de

Abstract

Many CS101 courses purport to teach object-oriented programming, but many seem to be directly translated from traditional structured programming courses. Lynn Andrea Stein’s "Rethinking CS101" program at MIT offers a radically different approach to teaching OO programming by concentrating on the interactive aspects of object-oriented systems. This approach has the added advantage that students who have previously learned "programming" must also relearn how to approach the problems involved in programming interactive systems. This paper reports on the author’s use of this concept outside of MIT, with encouraging results.

  1. Introduction

Traditional "Introduction to Programming" courses, often called CS101 in the United States, usually begin with a discussion of a small program that writes a string such as "Hello world!" to the screen. From there the different data types are discussed, the program flow structures are introduced and methods of changing the state of variables are presented. Procedures and functions are elaborated on and time is spent describing the various parameter passing mechanisms, and if there is time, an attempt is made to talk about pointers. Every week the students work on little programs, and with a bit of luck they can use linked lists by the end of the semester.

This method of teaching is especially pleasing for the young, typically male students who program as a hobby.

They think of themselves as a sort of code warrior, fighting with an enemy compiler, forcing it to assent to their glorious code and to produce a program that obeys their every desire. The result of this teaching method is often that the students play a syntax guessing game with the compiler. They do not understand the error messages, so they continually rearrange the syntax and attempt to recompile. If they happen to succeed – not necessarily with a program that does what they want, but at least with a program that compiles – they invent quite imaginative but usually wrong reasons as to why it does not work as desired. The reasons tend to have to do with the compiler or with the machine the compiler is running on, and so a new attack is planned to overcome the obstacles. Some eventually do discover a program which works. But if they fail to find a program that does what they want, the teacher is often faulted for not having taught the language right.

2 Rethinking CS101

Lynn Andrea Stein, Professor for Computer Science at the Massachusetts Institute of Technology, sees a large discrepancy between the traditional ways of instruction that encourage this solitary playing with small programs, and the ways of thinking that are needed for producing object-oriented programs in a team. Her project "Rethinking CS101" uses a radically different teaching methodology for introductory programming courses that emphasizes teamwork, documentation, and collaboration, while emphasizing the interactive aspects of object-oriented programming. This manner of teaching appeals to me because it removes the apparent advantage that code warriors have over beginning students of programming, and can in the long run help all students become good team programmers.

I have used the course and the methodology twice. The first time was during my sabbatical spent at Malmö högskola in Sweden, teaching in their 3-year Software Engineering program, and the second time in the 4-year Media and Computer Engineering program at the TFH Berlin in Germany. Currently, the course materials are in the process of being published by Morgan Kaufmann Publishers and a large-scale test of the methods is being conducted by the publisher. I have observed the beneficial effects of using this methodology, both in training students in desired programming and engineering behavior and also in combating the code warrior mentality. The purpose of this paper is to report on my experiences in using "Rethinking CS101".

3 Course structure

The course is structured around the idea of object-oriented programming being in essence the construction of interactive systems consisting of autonomous communicating objects, and not being primarily concerned with an algorithmic flow of control. The first chapter in the book begins with explaining the difference between the traditional form of programming – Stein calls it "Peanut Butter & Jelly Programming" – and interactive programming, which is modeled on the functioning of a restaurant. There we have objects such as patrons, waiters, cooks and cashiers that work on many different tasks at the same time.

The first pieces of Java that a student sees are literals and a discussion of types. Then names are introduced, with there being "shoebox names" for Java primitive values and "label names" for object values. Many everyday analogies and refreshing metaphors from a non-technical world are used to explain the theoretical concepts. The first complex types that the students see are interfaces, which are explained as contracts that an implementor must fulfill. Then a thorough discussion of expressions is given, which stresses the types of expressions.

Only now do the students get to see some statements, but only assignments, simple if and while statements, and the return statement. Methods are introduced as rules that tell an object how to behave, and the signatures for methods are discussed. The concept of class is then introduced as a recipe for making objects. The warriors are by now of course quite restless, since they have not yet seen a "Hello world" program, and even if they have been successfully hacking in C++ or Visual Basic for years, they are quite uncertain about what all this type stuff and these interfaces and classes are all about. They do not believe me when I tell them that we do very little "Hello world!" programming in industry. As will be seen below, the exercises are designed to make the students think about the concepts introduced without having to know how to design a complete program.

After classes there is a chapter on designing object oriented programs, followed by the introduction of exceptions, animacy and inheritance. The more advanced topics need not be taught in any particular order, but they include encapsulation, dispatch, event-driven programming, GUIs and the AWT, client/server and network programming, synchronization problems and recursion.

The book has a number of good exercises at the end of each chapter, but the most important aspect of the course are the large-scale experiments that the students are asked to conduct. MIT provides a code base for the exercises, the students make additions to the projects and experiment with the outcomes. The experiments follow a pattern that is common to many other engineering disciplines:

  1. The students must prepare for the experimentation lab by reading the lab materials before coming to class, and by doing so-called finger exercises, which are designed to guide their thoughts in the direction needed for working in the lab. The students must also have a rough sketch of a plan for what they intend to do in the lab. Students without finger exercises are not permitted into the lab, but must sit outside and complete their preliminary work. Real code warriors tend to be found outside at the beginning of the lab – they will complain that it was not clear what they were supposed to do and so they did nothing.
  2. Once in the lab, the students download the code, create a new project in their development environment, and begin experimentation. They are encouraged to discuss what they are doing with one another, the only request is that they note in their lab reports all the persons with whom they have collaborated. There is a fixed amount of time for the lab, the goal is not how many whistles and bells a student gets done, but the progress made and documentation recorded. This fixed amount of time puts pressure on the students to find an end to what they are doing, and not go on for as long as their families will permit them.
  3. The students check out of the lab by demonstrating that they have something that works, and then they must write a lab report documenting their plans and expectations, what they did in the lab and why, who they collaborated with, and how much time they spent on the exercise. The quality of this report is what is graded, not the extent to which they got things to work. They are expected to write in complete sentences, and such a report will often be upwards of 5 pages. The report is due inside of a week, failure to submit a timely report results in the entire lab being marked as missing in order to encourage the students to keep deadlines. This part of the lab is very difficult for many CS students, as they as a rule do not like to write. The code warriors may feel inadequate for not having done much, having wasted much time outside the lab planning, and will tend to submit overly short reports.

4 Experiences in use

My Swedish class consisted of about 30 students, with 5 women, 5 non-Swedish native language speakers, an age span of 19-40, and about 1/3 of the class with prior programming experience. The German group consisted of 60 students, with 11 women, only 5-6 non-German native language speakers, an age span of 18-45, and about 1/4 of the class with prior programming experience. The programming language experience tends to be Pascal, C(++) or Visual Basic.

The group with the prior programming practice seems to have the hardest time with the course. In this group we have both the code warriors and some students who genuinely want to learn how object-oriented programming works. The problem that they all seem to have is that they already have a structure in their minds, however wrong that structure might be, of how programming is done. When they hear me talk about interfaces they cannot put it in relationship with anything that they already know. Many code warriors use this as a reason to disregard what I say and to complain quite loudly that this is not the "right" way for programming to be taught. It is vital at this point to insist that they need more theory. I tell them that I will have to brainwash them, in order to get rid of their prior notions of what programming is.

In my first use of Stein’s method I only used the experimentation labs, as we only had a 8 week quarter, which rather exhausted the students. The second time I alternated using the exercises in the book one week and an experimentation lab the next. With an 18 week semester, this seems to be the right amount of exercise work.

The first experimentation exercise is just for getting acquainted with the development environment. It is a program that draws the well-known eyes that follow the cursor. Students are to load it, compile it, play with it, and try and change the color of the eyes and the labeling of a button. Surprisingly, many students need all four lab hours to do this. The code warriors will have fun experimenting with changing the size of the eyeballs and trying to make multicolor eyes, which occupies them for this session.

The second exercise gives the students a window with a little dot in it, and a controlling window in which they are to put expressions for determining where the ball should go next in each direction. They can make their own fields, if they wish, but all that is necessary is to return some value for both the x and the y coordinates. This seems confusing, as one tends to think of a dot as moving itself, but in this case it is something dragging the dot along the x or the y axis. This reinforces the idea that independent forces can be exerted upon an object. Those code warriors that have begun to understand what we are getting at will try and get the dot to draw circles and spirals. Others will balk and insist that the exercise is stupid. The rest of the students rather timidly try out this collaboration business – and discover that it is indeed permitted to talk with your neighbor. They begin exchanging ideas and showing each other how to do things. We spend a lot of time chasing missing semicolons and missing returns and puzzling over the jerky lines – since the x and y calculations are independent, sometimes they are done in a different order, causing interesting results.

The third one seems overly complicated for beginners – they are to design a network and write the code for a method that determines for a node how to transmit packets from the input channels to the output channels. The finger exercises made no sense to either group, but in the lab I walked them through looking up what I want to do in this interface, writing down the method name, and then using this as a parameter to a method from another class. It appears to be magic, some complain that the brainwashing has not yet been successful, but after a while it dawns on them how easy it is – and how bad the results are, because their node is merrily generating packets at will and dropping others on the floor. We are quite hampered by the utter slowness of the runtime system, and it is unfortunate that during some upgrade to a new and improved JDK, an object lost its toString() method, preventing us from storing and retrieving networks. Every time the OS crashes, the network has to be entered in by hand again. This tends to be used by some code warriors to prove how bad the methodology is, and they suggest we go do something more interesting like Roman Numeral Arithmetic.

Another exercise is the balancer, a little teeter-totter that can be balanced. The students are to write a method that asks the teeter-totter how far out of balance it is, and then reacts accordingly. They are encouraged to race their methods against one another, to demonstrate the power of interfaces. One of my code warriors spent over an hour at the board doing the physics of balancing (and scaring the daylights out of the rest of the class), until he realized that it was trivial: decide if I am above or below the balancing line, and give the method to move the teeter-totter either a positive or negative value to work with! The others soon realized that it was indeed of no matter how intricate their program was, the quality of the report was what counted. They began to relax, and enjoy experimenting. The contest appealed to the warriors, although they complained that they wanted to understand exactly how the entire thing worked. This is a great opportunity to explain that they have to learn to trust the work of others, to let go from the need to know about and control everything.

The last three exercises are quite ambitious: Given the GUI for a calculator, program a ButtonHandler that reacts to buttons being pressed and does the calculation. I am amused by the warriors, who make up elaborate (and wrong) methods of trying to get the operator precedence right. In the second semester, when we advance to data structures such as stacks, I will reveal the magic of reverse Polish notation. For now, they are beginning to realize that there is more to programming than just syntax!

Then they get to make a Scribbler, a simplified painting program for drawing colored lines and circles and squares. They now have to start a thread themselves, they can use utilities for a whiteboard and certain functions such as loading and saving, but they are on their own with the painting. Those that have learned to plan their work succeed, those that come to class without plans can’t keep up and miss the deadline. The last exercise is a simple client/server game called Cat and Mouse that needs even more planning to succeed. One student programs the cat, the other the mouse who gets chased around by the cat. While exploring the network classes some discover how easy it is to implement a simple chat program.

In Germany I dropped the last two experiments in favor of a 4-week mini-project. I had them design and implement a simple vending machine, including a GUI and an algorithm for making change with the least amount of coins. To keep things realistic, I changed the specifications every week. All of the students still active in the course had something working – and they had quite impressive class structures for first term students. Over half of my "warriors" were now enthusiastic class designers, as they realized how much it helped them cope with the ever-changing requirements. A few die-hards didn’t make it to a GUI, but at least they were able to report properly on the reasons why they didn’t get it to work.

5 Conclusions

So we do indeed, as promised by Stein, have students at the end of the first semester of programming capable of planning and implementing a simple application with a GUI. Unfortunately, since they have no reference as to what a student normally can do after such a course, some are unhappy as they feel that they have not learned to program – they see all these holes in their knowledge. I feel that it is much better for the students to be aware of their limited knowledge, than to believe that they can program. I had the privilege of seeing the results of the Swedish students programming projects done two quarters later. They were very well programmed, with good encapsulation and separation of concerns, nicely split into classes. Students with traditional programming instruction tend to have one, maybe two classes at the most, with everything done in the main class.

What about the code warriors? Well, some get converted and learn to plan what they want to do and to document as they go along (after all, they are usually very bright students). Some stay angry that they "didn’t learn programming right" and vent their anger in the official evaluation reports. Some fail the course, because they refuse to open their minds to the object-oriented way of thinking. I feel that this is good, as we do not need persons like this programming software in industry.

And the others? I feel that they are encouraged because they see a better picture of what programming is all about: planning, implementing and testing a system of communicating objects to solve a problem, not a game played against a compiler and a machine. They all learn teamwork, how to read documentation, and the value of documenting the development process, some very good habits for them to have. And in the end, despite the utter slowness of the programs, it actually is quite a lot of fun learning programming like this, even if it is much extra work for the teacher. So I will continue to teach Java in the manner, if I am forced to teach Java as a first language. I would prefer a different language, but that is another paper.