A Java-based CS1 course:
Not gentle enough!
David Gregg and Libero FicocelliGrande Prairie Regional College
ABSTRACTJava, a modern Object Oriented Language, is
becoming the language of choice for teaching introductory computer
science courses (CS1 and CS2) at most colleges and universities.
Previously, imperative languages like Pascal and C served this
purpose. This paper
discusses our experiences, observations and difficulties that have
arisen from switching our introductory computer science courses from
Pascal to Java. Some of the
more important challenges students faced with Pascal seem to be
significantly aggravated using Java and its object-oriented approach.
In general, the transition to Java has hindered students from
acquiring essential algorithmic techniques that are a necessary
prerequisite for developing appropriate programming skills. Although
students are initially excited about the ease in which they can create
graphical applications (using instructor-supplied templates), the
demands of the OOP paradigm soon becomes a frustrating exercise.
An analysis of CS1/CS2 student performance data, spanning three
years before and three years after the transition to Java, corroborates
the authors’ initial reservations regarding the potential impact of
the change in curricula. Although this deficiency is noticeable in the CS1 course, it
becomes especially evident during the CS2 course. Keywords: Java, Pascal, CS1, CS2, Education,
Programming-first, Computing, OOP, Weakness, Skill-set, Curriculum 1 Introduction
Grande Prairie Regional College is a regional community college,
which offers computing courses in either a 2-year Computer Systems
Technology diploma, a transfer stream with 2-year transferability to the
B.Sc. in Computing Science at the University of Alberta as well as a
collaborative degree B.Sc. in Computing and Information Systems with
Athabasca University. Students
in any of the above streams are required to take common introductory
programming courses. Four
years ago (Fall 1999), as a consequence of the fact that both our
primary transfer institutions adopted Java as a first language, we at
GPRC switched from Pascal to Java for our introductory programming
courses CS1-2 (CC2001 [1]). As
both institutions adopted the same textbook [2] we followed suit.
The textbook uses an object-oriented concepts and design
approach, with language features first.
Objects, behaviors and classes are introduced almost immediately
(page 4 of the textbook) and quickly progresses from using objects to
creating user defined classes. Applets,
GUI, and the event-driven model are interspersed throughout the early
chapters. These are
presented piecemeal, with limited continuity, from chapter to chapter.
Interactive I/O, file processing, and even network input are
introduced before primitives and control constructs are fully covered.
We structured our notes and lectures to parallel the material in
the textbook. This transition to Java as a first programming language presented a
number of interesting challenges. This
was not unexpected as even the authors of CC2001 clearly state that
using an object-oriented approach adds complexity to both the teaching
and learning of introductory programming.
After having offered the course during 4 successive years by 3
different faculty members, with multiple sections each fall, our primary
observation (primarily subjective and anecdotal) is: the
overall student skill set appears somewhat diminished when compared to
students who took the Pascal based version of the course.
Although students are on the whole reasonably successful at
building code with clearly defined and directed tasks, such as “fill
in the blank” classes and methods, we certainly find that they are
less adept at transforming general problem statements into appropriate
programs. When presented
with more challenging problems that require less glamorous
(non-graphical) and mundane problem decomposition techniques, they
display a marked lack of confidence, and an inability to assemble the
pieces into functional code. They
have limited intuitive sense for constructing conceptual models of
objects and behaviors used to solve real-world problems.
They can trace code, which uses classes, objects and methods, but
they have an incomplete understanding of when and why they are needed.
This is unfortunate because “programming is not a spectator
sport”, it’s not about watching, it’s about doing! We are deeply concerned that in our collective OO quest to avoid the
“dreaded poor programming habits syndrome” we are inadvertently
creating introductory visual programmers who are “algorithmically
challenged”. This may
sound somewhat heretical, however it is not inconsistent with the
content that they are being presented. There was already a great deal of material to be covered in the CS1
curriculum and the addition of new topics such as objects, GUI and
events requires that we displace something.
The fundamental question is whether we have displaced the right
things. More often than not, in order to be able to provide an early
introduction to objects and their behaviors, examples are usually
contrived and trivial, to the point where students find that they are
totally unrealistic (i.e. the Laugher Class).
Although we can buy some time by distracting them with pretty
colors and fancy interfaces, at some point we can no longer elude their
questions with trite and dismissive statements such as:
“trust me, soon you will understand why we have to do things
this way”; “don’t worry about what these terms mean, we will cover
them later”; 2 Is Java the problem?
During our own discussions as to the potential sources of perceived
weaknesses in our students, we deliberated as to our pedagogy.
What is it about Java that is causing the problem, or conversely
what good features of Java are we neglecting to emphasize?
During our review of numerous textbooks (prefaces are always
especially illuminating) we came across the following praiseworthy
features of Java:
Almost every author alludes to a similar list of “good features.”
Interestingly enough however, the authors often advocated quite
divergent approaches for the teaching of Java.
These included a graphics first approach, applications first,
objects first, events early, and so forth.
Other educators and researchers have also published similar
diverse opinions: including special I/O classes to hide Java’s
flexible but cumbersome I/O classes [3]; event-driven programming to
emphasize software skills necessary for 21st century
programming [4]; visual emphasis with AWT to motivate and prepare
students for the WEB [5]; and special front-end interfaces to facilitate
the use of object visualization and to hide the complexities of defining
and instantiating objects [6,7]. A superficial summary of their combined efforts would state that it
is important to introduce objects and events early/immediately, while
maintaining simplicity of code and the use of graphical emphasis to
motivate students. 3 Our Experience
The problems and frustrations that students express are often voiced
early to mid semester. This
period is where we deal almost exclusively with the introduction and use
of fundamental Java objects (strings, IO, graphics), provide an overview
of general program structure and layout as well as describing and
detailing the necessary components of classes, methods,
instance/local/parameter variables and of course, their respective
modifiers. There was a very evident easing of classroom tension later in the
semester when course curricula switches to covering primitive data
types, control structures and simple data structures.
Students find the context shift very refreshing!
This is clearly evidenced by increased student participation in
class discussions, more attentive attitude as well as a generally upbeat
mood and disposition. Perhaps
these are simply artifacts of having survived the post midterm
withdrawal frenzy, however the authors optimistically speculate these
changes are more likely attributable to content changes rather than
anxiety mediated endorphin release. In order to impart and facilitate student understanding of OO
principles, we have experimented with two basic approaches listed below,
these were supplemented with appropriate lab exercises. 3.1 Graphical EmphasisEarly in the course we describe applets and give lab assignments
which require the students to draw simple pictures using the Graphics
class. Ostensibly this is a
way to quickly demonstrate the ease of creating an applet, use of
numerous methods and practicality of parameters.
Although the students are initially excited by the ease with
which they can create colourful graphics, they quickly tire of the
tedium and repetition involved. Some
have even commented quite sarcastically, “I could have done it faster
and better using Microsoft’s paint program!” Obviously they missed the point of these exercises! More advanced graphics labs have included the use of standard
controls such as Buttons, Labels and TextFields.
In order to construct something useful, many such controls are
required, which means that the students replicate many similar lines of
code. Given that they have
limited knowledge with which to incorporate complex functionality, these
interface assignments quickly come to
resemble simple make-work projects. 3.2 Object EmphasisIn early assignments we give the students simple code skeletons and ask them to write code using string methods to achieve some simple I/O functionality. These include exercises, which manipulate strings for simple encryption, or read from various input devices to extract and print cleanly formatted output. At this point students are aware of objects and methods but are not yet ready to take control. In fact we tell them to disregard the code we provide as templates, especially the infamous: “public static void
main(String []args) throws Exception”. Actually the statement is very easy to understand if you ignore every
single token. As we continue to build on the Object fundamentals, we ask the
students to define and create rudimentary classes, starting with
simple/gentle code templates. (Others have adopted similar approaches using small,
directed, pieces of code [8] or programming by imitation [9].) Soon we get them to write complete classes using a supplied
specification that outlines the required methods and instance variables.
The problem that we encounter here is that since we have yet to
cover any control constructs the scope of the problem is limited and
viability of code is questionable. Students sense that the problems are
basically contrived and lose motivation for the task at hand.
The “novelty and excitement” of overloaded constructors and
methods can only take you so far! 4 Summary of Observations
Some of the challenges we faced have historical parallels that we
previously experienced with Pascal.
The same type of language features that mystified our Pascal
students (and others [10]), are haunting us now with Java.
Unfortunately the problems are even more pronounced.
In the past, we observed that our Pascal students had the greatest
difficulty when we got to the topics concerning procedures and
functions. This was
especially evident when we dealt with issues related to parameter
passing: pass by value and pass by reference; as well as the associated
concepts of variable scope and lifetimes. These difficulties are also implicit with the teaching of
Java, but are confounded because of early exposure [11]. Students struggle with a thorough understanding of the
basic differences between local and instance variables, parameters,
return values, object references and of course the instantiation of
classes via the often overloaded constructor method (which is like the
other methods but is not really the same).
And then along comes the keyword this, which we tell them,
is usually optional except when the scope is ambiguous. OOP requires that students understand references immediately, whereas
many CS2 (Pascal or C++) based students still have trouble with the
concept even after a full semester or more of programming.
We often hear the refrain that C always gives you enough rope to
do yourself serious injury especially when dealing with pointers.
Although Java theoretically protects you from pointer incursions
and abuses, the underlying complexity of reference visualization is not
attenuated. References
are problematic regardless of the context in which they are presented.
A statement such as “a
reference variable is a variable whose value is a reference”
is not a statement that is intuitively obvious.
If we then continue this discourse by adding that
“a reference variable is often used to hold the reference
that is returned from a constructor…” the result invariably
is a “glazed-eye, deer in the headlights ” stare of confusion. We eventually need to get around to explaining static, after
all we did promise on day one not to worry because we would explain it
later—some day real soon now! At
some point we have to bite the bullet and delve into the difference
between class methods and instance methods.
Of course we must not exclude discussion about a new kind of
variable that is shared by all instances of the class—the class
variable. All of the above are required understanding for even elementary OO
programs yet most students do not really possess the programming and
problem solving sophistication to adequately handle the rapid influx of
many new concepts. 5 ResultsAt GPRC we are in the final stages of the old stanine system for
course grading. A pass is a grade of 4 and above, to a maximum of 9.
A failure is a grade between 1 and 3. In the table below (all
numbers are percentages) we use WDF to denote those students who
withdrew from the course after the normal withdrawal date. Table 1 – Introductory Programming Courses (before and after
Java) A direct comparison of CS1 results from Table 1 indicates virtually
no change in student performance after the switch from Pascal to Java.
A more detailed breakdown of student’s grades is presented in
Figure 1. The chart of the
two data sets indicates similar patterns, however there is a slight
performance decrease in the midrange grades for the Java version.
(The distribution of the grades certainly does not resemble the
normal bell curve one would expect from most courses—a topic for
another paper.) The
performance decrease was surprising, only because our subjective
opinions seemed to suggest that the difference should have been even
greater! We expected
that the grades for the Java students to have been considerably lower
than the norms experienced with Pascal course.
Figure
1
- Comparison of CS1 (Java
vs Pascal) This discrepancy in our expectations prompted us to continue our
analysis; we collated similar data for our CS2 course.
Those results are presented in Table 1 as well.
Although we notice a 50% increase in failure rate (from 14.7% to
21.6%) the overall pass rates remain unchanged.
Continuing with the analysis, we charted grades for the Pascal and
Java versions of the CS2 course. For
clarity we present this data in separate figures.
Figure 2, which plots grades for the CS2 – Pascal version,
shows a normal distribution, whereas, Figure 3 presents a markedly
different profile. The
CS2-Java version seems to be bi-modal rather than normal.
This would indicate that most students fell into one of two
extremes—either they understood it or they did not! In retrospect, this result is actually consistent with our
expectations. In the CS1
course, weaker students who were not really able to master object
oriented concepts, were still able to perform reasonably well, given the
nature of the grading scheme. Approximately
70% of the grade is derived from quizzes, midterms, and finals, which
are for the most part: code tracing exercises; or given the prototype
write appropriate method bodies; or questions that present specified
classes where the students are required to instantiate and use methods.
There are few questions that ask students to write complete
programs. These exams are
modeled on exams given at our primary transfer institution.
Figure 2
- CS2 Pascal Version
Figure 3
- CS2 Java Version Given the manner in which we present the course material and the way
we evaluate, it would seem that many students are capable of achieving a
reasonable grade without actually have a firm grasp of the material.
This flaw is exacerbated in the CS2 course where it is imperative
that they actually understand the “substance” of the material that
was presented in CS1. Although
weak students (the ones who didn’t get it) are reasonably successful
at imitating and tracing, this weakness becomes overwhelming when they
are required to construct more complex programs.
It would seem that this result corroborates our initial
“subjective” opinion about the student’s inability to grasp OO
principles in the order and manner in which we are currently presenting
it. 6 Conclusion
A quote attributable to C.A.R. Hoare [10] “you can’t teach
top-down programming to beginning programmers, because they don’t know
which end is up”, has much in common with our current situation.
Perhaps, first time programming students have a difficulty
grasping OO programming, because they don’t know enough yet to realize
and appreciate that that objects can be extremely useful.
All they see is unnecessary complexity, which seems to add little
to the overall usefulness of their code. There will always be students, who “get it”
regardless of the language we teach or the paradigm we espouse, our
concern is for those students who populate the middle ground.
Is there something we can do for the average student so that they
can acquire the appropriate OO programming skills without the incumbent
frustrations that they currently experience? In the coming Fall semester we will attempt a retrograde approach
even though others [12] have deemed this a non-viable option.
We will focus on first teaching them primitive operations,
control constructs and primitive data structures before we delve into
full-blown Objects [13]. References[1] Computing
Curricula 2001 project (CC2001) Final Draft, Computer Society of
the Institute for Electrical and Electronic Engineers (IEEE-CS) and the
Association for Computing Machinery (ACM), December
15, 2001 [2] D. Arnow and G. Weiss, “Java An Object Oriented Approach”,
Addison Wesley Longman, 2 Ed, 2000 [4] K. B. Bruce, A. P. Danyluk and T.P Murtagh, “Event Driven
Programming is Simple Enough for CS1”,
Proceedings of the 6th conference on Information Technology in Computer
Science Education (ITiCSE 2001), Canterbury, 2001 [5] J. Corner and R. Roggio, “Teaching
a Java-based CS1 course in an Academically-diverse Environment”,
Proceedings of the Thirty-third SIGCSE Technical Symposium on Computer
Science Education (SIGCSE-02) [6] M. Kölling and J.
Rosenberg, “Guidelines for Teaching Object Orientation with Java”,
Proceedings of the 6th conference on Information Technology in Computer
Science Education (ITiCSE 2001), Canterbury, 2001 [7] S. Cooper, W. Dann
and R.Pausch, “Teaching Objects-first In Introductory Computer
Science”, Proceedings of the Thirty-fourth SIGCSE Technical Symposium
on Computer Science Education (SIGCSE-03) [8] S. Reges, “Conservatively Radical Java in CS1”, ACM
SIGCSE Bulletin , Proceedings of the thirty-first SIGCSE technical
symposium on Computer science education
March 2000 Volume 32 Issue 1 [9] R. Allen, K. Bluff, and A. Oppenheim, “Jumping in Java:
Object-Oriented Software Development for the Masses”, Proceedings
of the third Australasian conference on Computer science education
July 1998 [10 ] R. Pattis, “The ‘Procedures Early’ Approach in CS 1: A
Heresy”, ACM
SIGCSE Bulletin , Proceedings of the twenty-fourth SIGCSE technical
symposium on Computer science education
March 1993 Volume 25 Issue 1 [11] P. Andreae,
R. Biddle, G. Dobbie, A. Gail, L.Miller, and E. Tempero, “Surprises in
Teaching CS1 with Java”, Technical Report CS-TR-98/9 September 1998 [12] C. Alphonce and P. Ventura, “Object Orientation in CS1-CS2 by
Design”, Proceedings of the
7th conference on Information Technology in Computer Science Education (ITiCSE
2002), Aarhus, 2002 [13] C. Wallace, P. Martin and B. Lang, “Not Whether Java, But How
Java”, CTI Computing Monitor No. 8, 1997
David Gregg and Libero Ficocelli
|