A Semester-Long Project in
CS 2
Christine Shannon
Centre College
Danville, KY. 40422 USA
Introduction:
Two years ago, like many others, our Computer Science program
made the switch from Pascal to C++. As we had in the past,
we continued the practice of teaching some principles of software engineering
in the second course. However, object oriented design was more complex
than the top down design we had taught before and I was disappointed with
the level of expertise that students had achieved at the end of the course.
I was convinced that this was at least partly due to the type of assignments
I had given. Many were quite modest in size and designed to make
use of the current data structure we were studying. Except for the
classes provided by the authors to implement the new data structure, students
frequently added only one additional class to the project and they consequently
viewed the design phase as an unnecessary exercise. I subsequently
determined to construct a sequence of assignments that would be part of
a much larger project through which I could illustrate not only the use
of standard data structures but also the need for employing principles
of software engineering.
Major Features of the Semester Long Project:
-
Students will work in teams.
-
Team composition will change at each stage of the project
with only one student remaining with each project to maintain continuity.
This simulates typical workplace situations where programmers must write
to specifications designed by others and maintenance of code by non authors
is commonplace.
-
New data structures will be introduced into the project as
they are studied in the course so students must be prepared to institute
major changes in the project.
-
Students must provide a test plan for stages of the project
which involve programming. Teams will execute a test plan written
by another team as part of the testing procedure.
-
Documentation must be kept current as changes are made to
the project
-
Peer evaluations will assess the contributions of all members
of the team.
The Problem:
The problem was based on a laboratory exercise in the text
for the course, (Berman 33) and a similar problem in another text (Mercer,
596-647) which we were using in CS I. The object was to design a
library circulation system with a limited set of capabilities.
Step 1:
In the first phase of the problem students were given the
following description:
A library has requested a system that supports a small
set of library functions: checking out books, returning books, calculating
and paying fines. A book may be checked out for 14 days and late
fees are $.50 per day. No one may borrow a new book if they already
have 7 books checked out, or if they have one or more books overdue or
if they have unpaid fines of $5.00 or more.
Input will be through the keyboard and output will be
printed on the screen. Data on books and patrons will be stored
in an array and all searching will be sequential. Do not provide
for any library functions other than those listed in the problem.
They were to identify the classes, their responsibilities
and their collaborators. For each class, they were to list the data
to be stored and the functions to be executed. In addition to presenting
their design and descriptions to me in writing, they also had to discuss
them with me in my office. In these individual interviews, I asked
questions, pointed out errors, omissions, and made suggestions and then
each group was given the opportunity to make revisions before the final
version was submitted. Another technique that was useful both in
my office and while they were doing design was the acting out of scenarios.
For example, I might ask, "In what order will the various classes be involved
and what methods will be called when a patron wishes to check out a book?"
Several of the groups identified missing functions in this way. Because
my class was small, I was able to do all these interviews myself, but this
could certainly be handled by graduate assistants in a larger setting.
I had also considered the possibility of one group presenting its design
to another but worried about their lack of experience. In summary,
I wanted them to see that design was an important part of writing software
and I forced them to spend time on planning in spite of the fact that they
were eager to start coding.
Step 2:
Now the groups had to complete the specifications for each
design. This meant writing the header file for each class along with
pre and post conditions for each method and brief descriptions for each
data member. Students were warned that the specifications should be clear
enough so others could do the implementation. They were to
keep a log of changes to their original designs.
Step 3:
After teams were reassigned, they were now given the task
of writing to the specifications. A library of course needs books
and patrons so I provided them with a data file of patrons and a data file
of books in a simple to use format. In each design there were
arrays for storing this data and they now had to write additional methods
or functions to read this initializing data . By now, we had covered
linear search in the course.
The deliverables were:
-
all source code including header files and implementation
files
-
a main() that would read in the book and patron files
and provide a menu of library services. Several of the groups had
a class to control the system so they added the menu function in that class.
-
a clean copy of the test plan (to be used by another team)
-
an annotated version of the test plan showing the results
when each part of the plan was executed on their project, including notations
about errors that were corrected
-
a log of changes to the original specifications (e.g. additional
methods, changes in parameters etc.)
All groups produced running code which met the specifications
of the original problem although one project had a main() which
was very long and complicated. I anticipated that problems would
soon surface. Most test plans were too short, leaving out many test
cases that could easily lead to problems but all had tested the primary
functions extensively. I saved my highest praise for the test plan
which had uncovered some subtle errors. At this point where they
actually had a running program I wanted to emphasize that the test plan
wants to uncover errors.
Step 4:
By now we had learned about binary search, overloaded operators
and a variety of sorting procedures. They now knew that the linear
search we were currently using in our projects was not efficient.
In this phase of the project, the reconstituted teams were to sort the
data after it was read. The book and patron classes were supposed
to overload operators to do this. The search procedures were to use
binary search. Because we now knew about a variety of list classes,
each instance of the patron class had an instance of a list class to store
the collections of books that were checked out.
After making all these changes, each group executed
its test plan again to make sure all the results were identical and submitted
them along with all the source code. At this point the project was
quite complex and the careful design was beginning to show benefits.
In fact, during this stage one of the projects had to be abandoned.
It was much more weakly structured than the others and as changes began
to accumulate, the problems became obvious. Rather than force a group
to struggle to correct a project they had inherited from others, I permitted
them to select a different project to continue. It was a very good
learning experience.
Step 5:
The initial description of the problem had not allowed the
addition or deletion of either patrons or books because the array implementation
did not allow for efficient implementation of these operations. At
this point in the course, we had covered the ADT Table, and now the projects
were to be altered so that both books and patrons were maintained in hash
tables. The main menu was to be extended to allow for
the addition and deletion of patrons as well as books. These functions
were to be user friendly, allowing for error correction in the input.
This time the emphasis was on testing and I required a more extensive test
plan and thorough reporting on the results.
Step 6:
The final phase of the project required the use of inheritance to extend
the variety of materials which were maintained by the library. There
were now books, videos and CD-ROM's, each with their own regulations for
fines, and lending periods. I provided the new data file with the
extended offerings.
Course Evaluation Comments:
There were only 7 students in the class. The following are
their responses when asked to comment on the value of the semester long
project:
-
I thought the long term project was such a good idea. It
made me appreciate computers more, my peers more, and gave me a slight
understanding as to how the real world works.
-
The group project was good because it gave me a chance to
learn a lot more. Individual projects would have been worse for me. I learned
from working with others. It was also neat to see the project progress.
-
The project was good. A bit "boring" for lack of a better
word, but like we discussed, a "fun" program would have only meant more
work. I enjoyed working in groups as opposed to individually because the
combined knowledge of both programming helped immensely, and if you weren't
able to meet, the partner could help you out of a tight spot by doing some
work while you were busy. It's all good.
-
The group project was much better than individual projects
would have been. It is very helpful to have someone to collaborate with,
and it was really instructive to have to work on other peoples' code.
-
I think the semester long project is a great idea. It creates
a sense of accomplishment at the end of the term.
-
I really enjoyed the method of teaching. The group projects
were effective in continued programming learning
-
The project and homework balance was great, except when we
had to work in groups of three - (hard to get three people together). [Note:
with 7 students, there were two groups of two, and one with three. Because
students moved around with every phase of the project, they sometimes worked
in a group of three and sometimes in a group of two. Peer evaluations usually
mentioned that groups of three caused scheduling problems]
Conclusion:
The use of classes is far better this year than it was last
year. The final projects include a large variety of classes as well
as data structures. Early in the process, students realized the importance
of writing good code that was easy to maintain. The fact that one
project was aborted was a very good lesson. Student evaluations at
the end of the course were very positive. There were numerous comments
about their pride in what they had accomplished. Many of these students
were among those who took an introduction to software engineering course
the following spring. Both the instructor and the students felt that those
who had taken the new version of CS 2 were better prepared to work on the
large class project. At this point the evidence is largely anecdotal and
the numbers are small but student reaction was clearly positive.
Peer evaluations indicate good cooperation among the members of the teams
with scheduling difficulties the major deterrent to completely smooth operations.
I definitely intend to do this again next year with a different project
and perhaps trees instead of tables, but using similar increments in the
development of the project
Works Cited
Berman, A. Michael. Data Structures Via C++:
Objects by Evolution. New York: Oxford University Press. 1997.
Mercer, Rick. Computing Fundamentals with C++:
Object Oriented Programming & Design. 2nd ed. Wilsonville,
Oregon:
Franklin, Beedle & Associates, Inc. 1999.