Experiences Teaching Objects
A New Curriculum for First Year Computer Science Students
James Heliotis
Computer Science Department
Rochester Institute of Technology
102 Lomb Memorial Drive
Rochester, NY 14623-5608
585-475-6133
jeh©cs.rit.edu
This paper describes the lessons learned from teaching the first two of a set of new lower division courses in Computer Science. We have completely redone the curriculum to incorporate more of an object-oriented flavor. Courses now include much more of the pedagogy of software engineering. This results in less programming and far more code and design reuse than in previous years.
Although we are pleased, overall, with the results, they are not all positive. We felt it would be helpful to the computer science education community if we shared our philosophy and experiences in these courses.
A new, object-oriented software course sequence began last year at the Rochester Institute of Technology. Students of several computational majors take the sequence in their first year. This is but the first step in a rather bold overhaul of the Computer Science curriculum. We are also now defining a new Masters level curriculum. By far the boldest move, however, is our intent to offer one of the first undergraduate Software Engineering majors alongside the Computer Science major. The courses discussed in this paper are part of the lower division curriculum designed to meet the needs of both programs.
Having now taught each of the first two courses in the sequence twice, it seemed to us to be a good time for reflection. The discussion will focus on a few main areas: the software engineering perspective, teaching inheritance, student team work, and the impact of the language we chose.
An appendix contains materials that provide information about the curriculum itself.
Our curriculum consists of eight courses offered during the first two years of the Computer Science (and soon, Software Engineering) major. The courses are shown in Table 1.
Term Required Course Required Course
(quarter)
Fall, Year 1 Computer Science I
(CS1)
Winter, Yr 1 Computer Science II
(CS2)
Spring, Yr 1 Computer Science III
(CS3)
Fall, Year 2 Computer Science IV Professional
(CS4) Communication
Winter, Yr 2 Computer Organization Software Engineering
I I (SE1)
Spring, Yr 2 Computer Organization
II
Table 1: Required Courses for Computer Science Majors
During the first four courses, students learn about software development. The emphasized topics are:
This paper deals with the first two courses. During those six months, the students are exposed to all of the above topics in lectures, and in in-house laboratory exercises. The design methodology we chose was WirfsBrock [WIR90]. We felt that a flexible, non-rigorous approach would suit the students best at this point; SE1 could offer something more formal. The programming language the students use in these two courses is Eiffel [MEY92]. It is a pure object-oriented language that incorporates strong software engineering principles. Eiffel also has a simple syntax that keeps the students focusing on the higher level concerns of programming and design.
In CS1, we present the waterfall model of software development (again, to pick a simple first exposure) and objectoriented design. We then teach Eiffel, and two basic data structures, linked lists and stacks. This gives us enough material for numerous design and implementation examples. Towards the end of the course, algorithm design and stepwise refinement are addressed. Finally, we touch on some legal and ethical issues.
CS2 is the place where we work hard to drive home the idea of abstraction. We begin with a new data structure, the queue, and use it to create the more abstract notion of dispenser, to which both queue and stack belong. A discussion of trees and recursion follows. We then formally introduce the notion of inheritance, its uses, and its syntax and semantics in Eiffel. After a brief explanation of arrays, we wrap up the second quarter with design issues. Specifically, we discussed how to choose the right data structure to solve a problem, and what class hierarchies and application frameworks are.
Each course in the quarter system runs ten weeks. There are three hours of lecture in each week, plus a twohour supervised lab assignment. CS2 also included two larger design and programming projects. Many of the labs, and the first project, were team efforts, with teams being two or three people.
The sections that follow make up a retrospective on the first two courses, taught during the 1994-95 school year. At the time of the writing of this paper, CS1 has been offered two terms for a total of 7 lecture sections, and CS2 has been offered two terms for a total of 6 lecture sections.
Figure 1: Relationship between Computer Science and Software Engineering Curricula
In February of 1993, the Computer Science Faculty voted to make a transition in its early courses from the structured, modular language it was using, Modula-2, to an object-oriented language. Soon after this, however, another proposal began to gain momentum. The College of Applied Science and Technology, which contains C.S., would try to start a new B.Sc. program in Software Engineering, possibly in a joint effort with the College of Engineering. R.I.T. has always been a university with an undergraduate teaching orientation. It places more emphasis on training students for a viable career (not a first job), and less on research, than many other large private universities. The C.S. department therefore saw the new S.E. program as a major "spin-off" of C.S., with the potential of attracting many of C.S.'s traditional students. The reasons for this are clear: most R.I.T. C.S. graduates enter into what are now considered software engineering careers; few continue on into research and/or graduate study.
It was later decided that the two majors, S.E. and C.S., would share the same curriculum for almost the entire first two years before splitting (see Figure 1). Even after that, we expect many courses to count in both programs.
All of this helped us to realize that object orientation was not the goal. It is merely one of the many parts of the true goal of a computer science curriculum oriented toward software development rather than research. It is this realization that led us to the list of topics shown on Table 1.
On the very first day of class, a radical change was made. Instead of using the tried and true bottom up approach, where one introduces a computer and works up to primitive programming language elements, we tried to impart on the students a feeling for what it is like to design software. We talked about the problems in the industry today, and what people are thinking may be some solutions. We explored the software life cycle and discussed what could go wrong at each "step" in the process.
Before anything about instruction execution was mentioned, before conditional and iterative flow control were explained, we defined objects and classes. In fact, these were defined in a general way before Eiffel was even introduced. We also made it quite clear, first in lecture and then later in the laboratory, that it is unacceptable to begin implementing anything before an acceptable design is done.
Towards the end of the first quarter, however, we realized that we had made too much of a drastic departure from the traditional subjects. Our students were not good at going beyond the "feature list" for each class, i.e., they could not fill in the routines. We responded by adding a week on algorithm design. This proved quite useful, but the best teacher here turned out to be experience. Only after half of the second course did we see an appreciable comfort level from the students with respect to writing algorithms. We are currently in the process of developing a set of HTML-based exercises that the students will be able to do independently to improve their skills in this and several other areas.
Many of our laboratories deal with a framework we developed. It is a collection of card game artifacts from which solitaire games can be built. Graphical interface capabilities sufficient for displaying cards, selecting points in the "playing area", and pushing control buttons, were included. From this framework, we designed and wrote a card game that the students are asked to modify or enhance during several laboratory sessions in CS1. The latter project in CS2 is to use that framework to develop a different solitaire game.
From these artifacts came a watershed of ideas with which students rarely deal in the first year:
This was tough on the students, especially at first. In their first programming lab, they fetch a program of several hundred lines and are asked to make "trivial" changes to it, like modifying a string constant. To do this, they have to use a programming environment to which they were introduced only the week before, and wade through three files (classes), scanning code they cannot completely comprehend. This process excited some students, but scared many others. In later labs, their assignments become more challenging. The final card game lab in CS1 is to add a set of backup and redo commands to the solitaire game. We supply the MOVE_HISTORY class to keep information about the user's actions, and point out the places where the student has to modify the code to take advantage of its features.
Even when the assignments do not involve these card artifacts, partial designs and implementations are almost always provided. Other applications involve character graphics, a student transcript database, and Huffman coding. Students also do experiments on data structure efficiency (timing), library browsing, and inheritance-versus-client relationship choices (we discuss inheritance in detail in the next section). The reader must also keep in mind that, even without any designs or code provided by the course instructors, ISE Eiffel comes with a massive library of classes[MEY94] ready for the students to use in their designs.
When to teach inheritance has become an issue of intense debate. Those who advocate holding off inheritance and treating it as an advanced subject point to the fact that a data structures course never needed inheritance before. They also say that inheritance is closely tied to abstraction, and abstract concepts are difficult for beginning college students to grasp[CS195].
We were of a different mind. Inheritance is considered by many object technology advocates to be one of the core features that makes a language or methodology object-oriented. Without it, reuse is limited, and the ability to factor designs or implementations into components of manageable size is inhibited. We did, however, agree, that it does no good to teach it too early.
The first course, CS1, mentions inheritance from time to time. We use a simple design notation based on that used in Meyer's Eiffel text [MEY92] and taught the students how to indicate both client-supplier and inheritance relationships. Statements are made in passing about the class hierarchies they use in their laboratory exercises. We show the students where in a class definition the list of inherited classes can be found. We do not teach the syntax or semantics of inheritance in any detail. One laboratory has the students experiment with a class hierarchy of drawable shapes, but we provide all the classes in the hierarchy. Their job is only to write client code.
In the second course, in about the fourth week (40 hours of lecture since the beginning of the year), inheritance is formally defined and explained. Much, but not all, of the Eiffel syntax for inheritance is taught, and expected to be remembered. This knowledge is then reinforced via three lab experiments:
The results of this approach are promising. We can see from the test results that the students understood the issues involved in choosing inheritance versus "inclusion", or aggregation. This helped them comprehend class hierarchies and frameworks that were discussed later in the term. The issues concerning inheritance and a formal notion of type, however, need some more time. They also did not find Eiffel's notions of renaming and repeated inheritance easy to get used to.
A big part of preparing our students for industry is to have them do some work cooperatively. Over half the laboratory exercises in these first two courses is done in teams of two or three. The first project in CS2 is also assigned as a 3-person team project. It turns out, however, that the results from the labs and the project were quite different.
The laboratory instructors, for the most part, have positive things to say about the team experience. They feel the students were helped by having someone else with whom they could discuss ideas. It helped the students realize they were not alone in their inability to grasp everything from the start. There were negatives, however. If a bright student is matched with a slow student, but the bright student is unwilling to take the time to help the slow student keep up with what is being done, then the slow student gets farther behind. In fact, his/her situation may be worse than if there were no team labs. In a team, you can get away with letting others do most of the work. In each course, we passed out student surveys and asked how the students liked team-oriented labs. The response was favorable.
The first project assignment in CS2 is a grocery store simulation where the design and many of the lower-level objects are provided to the students. The students in turn must write the code that glues everything together and makes it run. The negatives of team work in the lab tended to be amplified in the project. Although lab assignments were often finished outside of the scheduled hours, the facts that there are two fixed hours per week, and that the lab is due in less than a week after that, helps keep the groups together and cooperating. For the project the students chose their own partners and had to plan their own meeting times and individual deliverables. Here is where the disparities really showed up. Some students hardly put in any effort at all, leaving the other(s) to do all the work. We accounted for this by requiring a team evaluation from each team member, rating his/her own contribution, and those of the other team members. However, when we got them back, we discovered an unanticipated problem. There were some bright students who were happy to do all the work because they believed the project would turn out better that way! These students would then fill out evaluations and report that their team members did not contribute at all. The team members would complain they were never given a chance to do so! This turned out to be quite a grading dilemma.
Currently we still believe that team work is a valuable experience, with two caveats:
There are some lessons we have learned specifically because of the programming language we chose. Others' experiences will differ from ours if another choice is made. The rest of the issues in this paper are likely to be valid as long as an object-oriented curriculum is followed.
There were only two text books available for Eiffel when we had to choose one in the spring of 1994 [MEY92][SWI93]. Both of these books were targeted for people who already knew how to program. This meant that the students had to rely heavily on their class notes. Since that time, three more texts have been written [THO95][WEI95][RIS95]. We have also intentionally kept our notes in electronic form, with figures and commentary, so that they, too, may someday be made into a text book.
As is the case with many programming environments these days, ISE's ebench is a sophisticated tool for professional programmers. That is, it is set up to make it easy to manage large projects containing tens or hundreds of thousands of lines of code. This makes it a bit more difficult for a beginner to log in and create a "hello world" program. This problem is not unique to Eiffel. Look at Borland C++ 4.5, and compare it to an older version of Turbo C++, and decide which you would rather use as a tool in CS1 (fancy graphics aside!).
Most students quickly abandoned the fancy graphical user interface, and used the command line compiler, es3. Because of this, they gave up most of the browsing and debugging capabilities, but their sophistication level is not to a point where these things mattered to them enough.
One secondary gain we thought we might have by choosing a less well known language (and the somewhat less well known object paradigm) was that no students would be at an advantage over the others by having already taken a programming course in high school. This turned out not to be true. At first, there were looks of confusion on the faces of the Pascal, Basic, and C programmers in our classes who did not understand what we were doing or why. However, they soon became acclimated and passed by those with no prior experience. We feel their experience helped them develop algorithms (and specifically loops) more easily.
We were pleased to discover many of our more skeptical students turning around and admitting that Eiffel was a "fun" language in which to work.
The interest level is definitely higher this year than when we taught the old sequence. We see many reasons for this.
The attendance in lectures is up, because the students had very little from their past experiences that would help them get by. Some students used to look at the first year courses as too easy, only to realize they had missed important information once it was too late for them to catch up.
Attendance in laboratories is up as well (near 100%, discounting students who eventually drop). This is partly due to the above reasons, but also because the experiments were "more fun" than the classic TTY-based assignments their predecessors received. There is another, independent reason for this higher attendance, however. The lab instructors have made an effort to be pro-active during the lab, instead of sitting at a workstation in the corner and saying, "I'm here if you want me." This helps immensely.
We had hoped to make a "kinder and gentler" curriculum, as the saying goes. We switched to objects (everyone knows about objects in the "real world") and graphics (should be more like a video game!). Nevertheless, the material is challenging. Although we feel more organized and productive in what we are teaching, one cannot escape the fact that many of our topics, e.g., abstraction, polymorphism, design frameworks, and event handling, are sophisticated and force the students to work hard to keep up.
We are quite pleased with the overall results. We are not planning any major changes for this year.