Guide to Java: A Concise Introduction to Programming (2nd Edition) James T. Streib instant download
Guide to Java: A Concise Introduction to Programming (2nd Edition) James T. Streib instant download
https://ebookmeta.com/product/guide-to-java-a-concise-
introduction-to-programming-2nd-edition-james-t-streib/
https://ebookmeta.com/product/concise-guide-to-databases-a-
practical-introduction-konstantinos-domdouzis/
https://ebookmeta.com/product/a-concise-introduction-to-robot-
programming-with-ros2-1st-edition-francisco-martin-rico/
https://ebookmeta.com/product/introduction-to-programming-with-
java-a-problem-solving-approach-3rd-edition-john-dean/
https://ebookmeta.com/product/the-eagle-has-eyes-the-fbi-
surveillance-of-cesar-estrada-chavez-of-the-united-farm-workers-
union-of-america-1965-1975-1st-edition-jose-angel-gutierrez/
War in the Mountains: Peasant Society and
Counterinsurgency in Algeria, 1918-1958 1st Edition
Neil Macmaster
https://ebookmeta.com/product/war-in-the-mountains-peasant-
society-and-counterinsurgency-in-algeria-1918-1958-1st-edition-
neil-macmaster/
https://ebookmeta.com/product/stunt-doubled-roommates-3-1st-
edition-stephanie-brother/
https://ebookmeta.com/product/software-telemetry-1st-edition-
jamie-riedesel/
https://ebookmeta.com/product/fakemas-a-holiday-instalove-
romance-briar-vale-1st-edition-gia-bailey/
https://ebookmeta.com/product/handbook-factory-planning-and-
design-1st-edition-hans-peter-wiendahl/
Wavelet Analysis: Basic Concepts and Applications 1st
Edition Sabrine Arfaoui
https://ebookmeta.com/product/wavelet-analysis-basic-concepts-
and-applications-1st-edition-sabrine-arfaoui/
Undergraduate Topics in Computer Science
Guide to Java
A Concise Introduction
to Programming
Second Edition
Undergraduate Topics in Computer Science
Series Editor
Ian Mackie, University of Sussex, Brighton, UK
Advisory Editors
Samson Abramsky , Department of Computer Science, University of Oxford,
Oxford, UK
Chris Hankin , Department of Computing, Imperial College London, London, UK
Mike Hinchey , Lero – The Irish Software Research Centre, University of
Limerick, Limerick, Ireland
Dexter C. Kozen, Department of Computer Science, Cornell University, Ithaca,
NY, USA
Andrew Pitts , Department of Computer Science and Technology, University of
Cambridge, Cambridge, UK
Hanne Riis Nielson , Department of Applied Mathematics and Computer Science,
Technical University of Denmark, Kongens Lyngby, Denmark
Steven S. Skiena, Department of Computer Science, Stony Brook University, Stony
Brook, NY, USA
Iain Stewart , Department of Computer Science, Durham University, Durham,
UK
Joseph Migga Kizza, College of Engineering and Computer Science,
The University of Tennessee-Chattanooga, Chattanooga, TN, USA
‘Undergraduate Topics in Computer Science’ (UTiCS) delivers high-quality
instructional content for undergraduates studying in all areas of computing and
information science. From core foundational and theoretical material to final-year
topics and applications, UTiCS books take a fresh, concise, and modern approach
and are ideal for self-study or for a one- or two-semester course. The texts are all
authored by established experts in their fields, reviewed by an international advisory
board, and contain numerous examples and problems, many of which include fully
worked solutions.
The UTiCS concept relies on high-quality, concise books in softback format, and
generally a maximum of 275–300 pages. For undergraduate textbooks that are
likely to be longer, more expository, Springer continues to offer the highly regarded
Texts in Computer Science series, to which we refer potential authors.
James T. Streib Takako Soma
•
Guide to Java
A Concise Introduction to Programming
Second Edition
123
James T. Streib Takako Soma
Program in Computer Science Program in Computer Science
Illinois College Illinois College
Jacksonville, IL, USA Jacksonville, IL, USA
This Springer imprint is published by the registered company Springer Nature Switzerland AG
The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland
Preface
Purpose
The purpose of this text is to help the reader learn very quickly how to program using the
Java programming language. This is accomplished by concentrating on the fundamentals,
providing plenty of illustrations and examples, and using visual contour diagrams to
illustrate the object-oriented semantics of the language.
Need
This text attempts to fill the gap between the above two types of books. First, it provides
plenty of examples and concentrates primarily on the fundamentals of the Java
programming language so that the reader can stay focused on the key concepts. Second, by
concentrating on the fundamentals, it allows the text to be more concise and yet still
accessible to readers who have no prior programming experience. The result is that the
reader can learn the Java programming language very quickly and also have a good
foundation to learn more complex topics later.
v
vi Preface
The second edition retains all the features of the first edition. In addition to fixing any
known errors, any areas that could be clarified have been reworded. Features new to the
second edition, include the following:
Typically, there are three ways objects can be introduced to the beginning programmer:
Objects first.
Objects last.
Objects interleaved.
This text takes the latter approach where objects are discussed in Chapters 2, 5, and 9.
However, recognizing that some readers and instructors might want to use one of the first
two approaches, this text can be read using alternative orders. For example, should an
viii Preface
objects first approach want to be taken, after reading Chapter 1, Chapters 2 and 5 can be
read next, followed by Chapters 3 and 4. Should an object later approach want to be used,
Chapters 3 and 4 can be read prior to Chapters 2 and 5.
To help facilitate these alternative approaches, starting with Chapter 3, the Complete
Program sections at the end of each chapter have examples with and without using objects.
Note that Chapter 9 requires an understanding of arrays, which is covered in Chapter 7,
and it can be read after completing that chapter.
Scope
As mentioned previously, this text concentrates on the fundamentals of the Java
programming language such as input/output, object-oriented programming, arithmetic and
logic instructions, control structures, strings, arrays including elementary sorting and
searching, recursion, files, bit-wise logic, and parallel processing programming. As a result,
it might not cover all the details that are found in some other texts, and if necessary, these
topics can be supplemented by the instructor or reader, or covered in a subsequent text
and/or second semester course.
Audience
This text is intended primarily for readers who have not had any previous programming
experience; however, this does not preclude its use by others who have programmed
previously. It can serve as a text in an introductory programming course, as an introduction
to a second language in a practicum course, as a supplement in a course on the concepts of
programming languages, or as a self-study guide in either academe or industry. Although
no prior programming is assumed, it is recommended that readers have the equivalent of
an introduction to functions course that includes trigonometry which will help with
problem solving and understanding the examples presented in the text.
Acknowledgments
In addition to the reviewers of the first edition, the authors would like to thank Mark E.
Bollman of Albion College and James W. Chaffee of the University of Iowa for their
continued work on this edition. Also, the authors would like to acknowledge the students
of Illinois College who have read and used various sections of the first edition in the
classroom. On a personal note, James Streib would like to thank his wife Kimberly A.
Streib and son Daniel M. Streib. Takako Soma would like to thank her family and friends,
near and far.
Note that Java is a registered trademark of Oracle and/or its affiliates and that Windows
is a registered trademark of Microsoft Corporation in the United States and/or other
countries.
Feedback
The possibility of errors exist in any text, therefore any corrections, comments, or
suggestions are welcome and can be sent to the authors via the e-mail addresses below. In
addition to copies of the complete programs presented in the text, any significant
corrections can be found at the website below.
Preface ix
Website: http://www.jtstreib.com/GuideJavaProgramming.html
xi
xii Contents
1.8.5 Summing 41
1.8.6 Arithmetic Functions 42
1.9 Comments 43
1.10 Complete Program: Implementing a Simple Program 44
1.11 Summary 46
1.12 Exercises (Items Marked with an * Have Solutions in Appendix E) 47
2 Objects: An Introduction 51
2.1 Introduction 51
2.2 Classes and Objects 51
2.3 Public and Private Data Members 52
2.4 Value-Returning Methods 52
2.5 void Methods and Parameters 53
2.6 Creating Objects and Invoking Methods 54
2.7 Contour Diagrams 56
2.8 Constructors 62
2.9 Multiple Objects and Classes 66
2.10 Unified Modeling Language (UML) Class Diagrams 73
2.11 Complete Program: Implementing a Simple Class and
Client Program 75
2.12 Summary 77
2.13 Exercises (Items Marked with an * Have Solutions in
Appendix E) 78
3 Selection Structures 83
3.1 Introduction 83
3.2 If-Then Structure 83
3.3 If-Then-Else Structure 88
3.4 Nested If Structures 91
3.4.1 If-Then-Else-If Structure 91
3.4.2 If-Then-If Structure 94
3.4.3 Dangling Else Problem 96
3.5 Logical Operators 99
3.6 Case Structure 105
3.7 Complete Programs: Implementing Selection Structures 111
3.7.1 Simple Program 111
3.7.2 Program with Objects 114
3.8 Summary 116
3.9 Exercises (Items Marked with an * Have Solutions in Appendix E) 116
6 Strings 203
6.1 Introduction 203
6.2 String Class 203
6.3 String Concatenation 204
6.4 Methods in String Class 206
6.4.1 The length Method 206
6.4.2 The indexOf Method 206
6.4.3 The substring Method 207
6.4.4 Comparison of Two String Objects 209
6.4.5 The equalsIgnoreCase Method 211
6.4.6 The charAt Method 212
6.5 The toString Method 213
6.6 Complete Program: Implementing String Objects 215
6.7 Summary 219
6.8 Exercises (Items Marked with an * Have Solutions in Appendix E) 219
7 Arrays 223
7.1 Introduction 223
7.2 Array Declaration 223
xiv Contents
8 Recursion 265
8.1 Introduction 265
8.2 The Power Function 265
8.3 Stack Frames 274
8.4 Fibonacci Numbers 277
8.5 Complete Program: Implementing Recursion 289
8.6 Summary 291
8.7 Exercises (Items Marked with an * Have Solutions in Appendix E) 291
Index
0
Introduction to Computing Concepts
James T. Streiba* and Takako Somaa
a
Computer Science Program, Illinois College, Jacksonville, IL, USA
Abstract
In addition to an introduction to hardware and software concepts, including the concept of compiling,
interpreting, and executing a program, there is an introduction to computational thinking, software design,
and computer ethics.
Keywords
Hardware, Software, Computational Thinking, Software Design, Computer Ethics.
0.1 Introduction
Although this chapter is labeled as Chapter 0, that does not diminish its importance. The
reason for such a numbering is to allow readers with a previous introduction to computing
concepts and programming to proceed onto Chapter 1. However, for readers with no prior
introduction or for those who would like a refresher, this chapter provides an important
overview of hardware, software, computational thinking, software design, and computer
ethics.
0.2.1 Hardware
As many readers may already know from using application software such as a word
processor, a computer system is composed of two major parts: hardware and software.
Since this book is primarily about writing software, this section on hardware is
understandably brief. The hardware is the physical computer that includes five basic
components: the central processing unit (CPU), the random-access memory (RAM) or just
memory for short, input (typically a keyboard), output (typically a monitor), and storage
(often a disk) as shown in Fig. 0.1.
CPU
Input Output
RAM
Storage
0.2.2 Software
Compiler Assembler
The solution to making programming easier and allow programs to be used on different
machines is through the use of high-level languages which are more English-like and math-
like. One of the first high-level programming languages was FORTRAN (FORmula
TRANslation), which was developed in the early 1950s to help solve mathematical
problems. There have been a number of high-level languages developed since that time to
meet the needs of many different users. Some of these include COBOL (COmmon
Business Oriented Language) developed in the 1950s for the business world, BASIC
(Beginners All-purpose Symbolic Instruction Code) developed in the 1960s for beginning
programmers, Pascal in the 1970s previously used for teaching computer science students,
C in the 1970s for systems programming, and C++ in the 1980s for Object-Oriented
Programming (OOP).
Java is also an OOP language that was developed at Sun MicroSystems (which is now
a subsidiary of Oracle Corporation) and was released in 1995. OOP is a programming
methodology that makes it more convenient to reuse software and will be discussed further
in Chaps. 2 , 5 , and 9 .
If high-level languages are easier to learn and use, how can they be implemented on a
computer that can only understand machine language? Similar to assembly language
needing an assembler, the program needed to translate a high-level language to a low-level
language is a compiler or an interpreter. Although there is a one-to-one correspondence
between assembly language and machine language, there is a one-to-many correspondence
4 0 Introduction to Computing Concepts
between a high-level language and a low-level language. This means that for one high-
level language instruction, there can be many low-level assembly or machine language
instructions. Even though different CPUs need different compilers or interpreters to
convert a particular high-level language into the appropriate machine language, compilers
and interpreters allow the same high-level language to be used on different CPUs.
The difference between a compiler and an interpreter is that a compiler will translate
the high-level language instructions for the entire program to the corresponding machine
language for subsequent execution, whereas an interpreter will translate and then execute
each instruction one at a time. Further, a compiler might translate directly to machine
language, or it might translate the high-level language to assembly language, and then let
an assembler convert the assembly language program to machine language as shown in
Fig. 0.2. Once the machine language is created, it is subsequently loaded into the
FRPSXWHU¶V5$0DQGH[HFXWHGE\WKH&38
As mentioned above, an interpreter works slightly differently than a compiler. Instead
of converting an entire high-level program into machine language all at once and then
executing the machine language, an interpreter converts one line of the high-level program
to machine language and then immediately executes the machine language instructions
before proceeding on with the converting and executing of the next high-level instruction
(see Fig. 0.3). The result is that compiler-generated code executes faster than interpreted
code because the program does not need to be converted each time it is executed. However,
interpreters might be more convenient in an educational or development environment
because of the many modifications that are made to a program which require a program to
be converted each time a change is made.
Compile Interpreter
2. Then execute all the machine 2. And then execute only the corresponding
instructions machine instructions
Java is somewhat unique in that it uses both a compiler and an interpreter to convert the
high-level instructions to machine language. A compiler is used to convert the Java
instructions into an intermediate-level language known as bytecode, and then the bytecode
is converted into machine language using an interpreter.
Since the intent of Java was for portability on the World Wide Web, the advantage of
using both a compiler and an interpreter is that most of the translation process can be done
by the compiler, and when bytecode is sent to different types of machines, it can be
translated by an interpreter into the machine language of the particular type of machine that
the code needs to be run on (see Fig. 0.4).
Note that just as there can be a one-to-many relationship between high-level and low-
level instructions, there can be a one-to-many relationship between Java and bytecode.
However, unlike the one-to-one relationship between assembly language and machine
language, there can also be a one-to-many relationship between bytecode and machine
language, depending on the machine for which the bytecode is being interpreted.
Interpreter
Compiler
solution can be used to solve new problems. Abstraction is the filtering out of
unnecessary information. In other words, taking a step back from the specific details and
focusing on the big picture allows one to create a more generic solution. Algorithms are
step-by-step instructions to solve a problem. It is important to create a plan, an algorithm,
for the solution when solving a problem. Logical thinking is deductive inference of new
information on existing information. Computational thinking is a problem-solving
process that involves a number of core principles from computer science as mentioned
above.
But how can these principles be used in non-programming context, for example, solving
the Tower of Hanoi game? The Tower of Hanoi game consists of three pegs, and initially
one of the non-centered pegs contains several rings stacked in order of descending
diameter from bottom to top. The goal is to move the stack of rings to another non-
centered peg as shown in the Fig. 0.5.
During the process, only one ring can be moved at a time which means only a top ring is
removed among the towers at any given time. Consequently, several rings cannot be
moved at once. Another rule is that a bigger ring cannot be placed on the top of a smaller
one. At the start of the game, the only ring that can be moved is the smallest ring and it
may be placed on one of the two pegs. Next, there are two rings that can be moved. There
is no good reason to move the smallest one back to the original stack or to another peg.
So, the next move should be moving the second smallest ring. As it cannot be stacked on
the top of the smallest one, naturally it goes on the other peg. By understanding the rules,
logical thinking is used to determine the next step. When making a move, do not be
distracted by color of the rings or pegs, nor the sounds they make, but focus on the rings.
This is simplifying the problem using abstraction. As in Fig. 0.6 after successive moves,
there is a point where the largest ring is on one peg and rest of the rings are stacked on
another peg in order the largest to the smallest from the bottom to the top. Realize that
during the moves, a ring can be placed on the top of any ring that is bigger than itself, not
merely the next larger ring.
0.3 Introduction to Computational Thinking 7
Now the task is to move the stack that has one smaller number of rings. During the
process there will be a situation where the second largest ring is on the top of the largest
one and the rest of the rings are stacked in correct order on another peg as shown in Fig.
0.7.
Fig 0.7 The largest and the second largest rings in the final position
Notice that every time the largest ring of the particular stack is placed in the final
position, the next problem is to solve the same problem with one less number of rings,
which means the task to solve the Tower of Hanoi game is divided into smaller problems
using decomposition. Also realize that the same technique can be used to solve the
problem with different sizes by seeing the pattern. Making a plan of where to moving a
ring is step-by-step procedure, which is an algorithm.
be made between the syntax and the semantics of a program. Simply stated, the syntax is
the grammar of the language, and the semantics is the meaning or what each instruction
does. To explain further, syntax is the spelling of the individual words, where the
semicolons go, and so on. If mistakes are made, a compiler will detect what are known as
syntax errors, generate messages to the programmer, and the program will not be compiled
or executed. Although syntax is very important, there is a tendency for first-time
programmers to spend too much time learning syntax to avoid syntax errors. However,
there must be equal time spent on semantics to ensure that the program does what the
programmer intended it to do.
Even though there might not be any syntax errors, there can be what are called execution
errors or run-time errors, such as division by zero. When these types of errors occur, the
appropriate error messages are generated and execution stops. Even worse, there can also
be logic errors, which are mistakes in the logic of the program so that the program does
not do what was intended. The unfortunate aspect of logic errors is that they do not produce
any error messages which can make them extremely difficult to find and fix.
As an analogy, an individual might be able to build a small storage shed by just sawing
and nailing some lumber together without worrying about the overall design of the project.
However, with a larger project such as a house, apartment building, or office building, that
methodology would not be sufficient. Instead, there are many other people who must be
consulted, including the original customer who wants the building built, the architects who
work with the customer, the contractors, and the carpenters. The same holds true in the
world of programming where a programmer and/or systems analyst works with others such
as customers, users, and managers.
What are needed are various strategies and tools to help write programs correctly to
minimize logic errors. Just as in the above example where blueprints and plans are used by
the architect, there are techniques that can be used by analysts, software engineers, and
programmers. Although the complete process for developing software might not be needed
initially with smaller programs, it does not hurt to practice the various techniques on
smaller programs to gain familiarity, so that when one advances to more difficult projects,
one is comfortable with many of the techniques. Although the following techniques are
used primarily with non-object-oriented programs, they can be augmented with object-
oriented design techniques introduced in chapter 2 and used in larger programs.
0.4 Essentials of Software Design 9
There are many different methodologies and number of stages within the various
methodologies for solving problems that can be found in different texts, but upon closer
examination, they are all rather similar. They tend to include at least four stages, and they
are usually comparable to the following:
1. Analysis
2. Design
3. Implementation
4. Maintenance
0.4.2.1 Analysis
The analysis stage is where the needs of the user or customer are first determined.
Questions concerning the form and quantity of the input, the type of processing that needs
to be done, the storage requirements of data, and the type of output needed are asked and
clarified at this stage. This would be similar to a customer in a construction project trying
to determine what type of building should be built. In a first semester programming class,
this stage may or may not be included. Sometimes a professor might have already
completed the analysis stage and included what is needed in the programming assignment.
However, at other times, they might require this stage and a number of questions will need
to be asked by the student. This might be especially true when working on a team project
in a software design or senior capstone course.
0.4.2.2 Design
The design stage is where a project begins to take shape. It is similar to the architect
creating a set of blueprints and models for the user to examine, because changes are much
easier to make on paper or with the model than once the construction of the building has
started. Various tools such as pseudocode and Unified Modeling Languge (UML) diagrams
(discussed shortly) are used by systems analysts, software engineers, and programmers to
help design the program. Again, it is much easier to make changes during the design phase
than after the programming has begun.
0.4.2.3 Implementaion
The implementation stage is where the code is actually written, entered, compiled, and
syntax errors are corrected. Once the code is free of syntax errors, it is thoroughly tested.
This includes testing various components of the program to be sure each section is working
properly. If not, the code needs to be debugged to correct any logic errors. In addition to
the various components, the entire program needs to be tested to ensure that all the
components work together as planned. Sometimes errors are a result of not following the
design, whereas other times, it is not necessarily the code but rather the design itself that
has the error, in which case one has to go back and correct the error in the design. The
result is that the stages above do not necessarily need to be rigorously adhered to, but rather
when at a stage one may need to return to a previous stage for clarification or to fix a
possible error.
10 0 Introduction to Computing Concepts
0.4.2.4 Maintenance
The maintenance stage is where all the modifications and updates take place. In an
industrial strength program, more time is spent in the maintenance phase than all of the
three preceding stages. This is because once a program is up and running, there can be
numerous changes that need to be made over the lifetime of a program. This is another
reason why a program should be designed well in order to facilitate modifications later in
the life of a program. Unfortunately, beginning programmers do not often experience this
stage of a program, because once the concepts are learned from one programming
assignment, the program is often not used again and another program is assigned to
introduce the next set of concepts. However, in some upper-level courses, the assignments
get longer, existing programs might be modified and reused, and students get to have some
experience with the maintenance stage of programs. Regardless, it helps even beginning
students to design well-thought-out programs to gain practice in the event that a professor
decides it might be easier to modify an existing program rather than having to design a new
program from scratch, as done in the real world.
0.4.3.1 Pseudocode
One technique that can help during the design stage is the use of pseudocode.
Pseudocode is a combination of English and a programming language. Since it is not a
SURJUDPPLQJODQJXDJHWKLVLVWKHUHDVRQIRULWVQDPHDV³SVHXGR´FRGH7KHDGYDQWDJHRI
using pseudocode is that one can concentrate on the logic of an algorithm and not worry
about the syntax of a particular programming language. In fact, well-written pseudocode
should be understood by any programmer regardless of the programming language that
they use, and they should be able to convert the pseudocode into their particular
programming language. However, there can be many different versions and levels of detail
WKDWFDQEHLQFOXGHGLQSVHXGRFRGHVRLWLVEHVWWRFKHFNZLWKRQH¶VLQVWUXFWRURUFRPSDQ\
for any preferences or standards that are employed. As a simple example, consider the
following pseudocode on the left compared to the Java statement on the right:
At this time it is not nececessary to understand the Java code on the right. However, note
that the verbal description on the left is much easier to understand than the detailed Java
0.4 Essentials of Software Design 11
code. As a result, one does not need to concentrate on the intricate syntax, but rather the
semantics. As an alternative, notice the more specific pseudocode on the left.
Both the pseudocode and the Java code are known as assignment statements as will be
discussed in the next chapter. Note that an arrow is used in the pseudocode instead of an
equal sign in the Java code to indicate an assignment statement. This helps illustrate the
direction of assignment, since some languages use symbols other than an equal sign to
illustrate assignment. Also notice that a mathematical symbol is used instead of an asterisk
to illustrate multiplication. Lastly, a semicolon is not used since not all other languages use
them to terminate statements.
The result is that the pseudocode in the second example is more specific than the first
example which helps with the translation to Java, but it is also more generic than the Java
statement which helps in the translation to other languages as well. Again, these are just
two samples of pseudocode, so be sure to check your local guidelines and requirements
which should be used. In this text, when pseudocode is used, it will be written with as much
detail as possible so as not to be ambiguous and to help with the translation into Java.
0.4.3.2 OOP and UML
Since the term object has been used previously, what is an object? In the past, programs
were often written with large sections of code that were not very helpful to reuse when
another program needed to be written.
It can help with the understanding of the idea of objects to think of an automobile. An
automobile has many different parts such as steering mechanisms, transmissions, brakes,
etc. Instead of designing the transmission as unique to only one type of auto, a generic plan
for a transmission can be designed first. Then particular versions of the transmission could
be built to be put into different types of automobiles. The plans for the transmission can be
thought of as a class and the differing versions of the transmission as instances of that class,
or in other words, objects. This way a whole new design for a transmission does not need
to be created for each type of auto, but rather just a different variation. The same applies to
software, where a whole new complete design does not need to be created but just a
different version of the original class. Although this is just a brief glimpse of objects, this
same idea can be applied to software and a more complete discussion will be presented in
Chapter 2.
Unified Modeling Language (UML) is a visual method used to help contruct a program
using classes and objects. One might ask since Java is an Object Oriented (OO) language
and UML is helpful in creating an OO program, why would one need pseuodocode? The
answer is because each class and instance of a class or object contains code, pseudocode
can help with the design of the class. So whereas UML helps with the creating of classes
and objects, pseudocode helps with the creation of code within classes and objects. UML
will be discussed further in Section 2.10.
12 0 Introduction to Computing Concepts
0.4.3.3 Debugging
Even when all attempts to write a logically correct program are followed, the possibility of
logic errors still exists. The process of finding and fixing logic errors is known as
debugging. When trying to debug a program, a programmer should not start to randomly
alter code in the hope that the error might be fixed. Although this might work occasionally
with smaller programs, it rarely works as programs become larger and more complex.
Instead, one should look for patterns in the output in an attempt to isolate the problem.
Further, one needs to carefully check the program by walking through the code to ensure
that it is doing what was originally intended.
To assist in this process many Integrated Development Environments (IDEs), which are
used to enter, edit, compile, and execute a program, sometimes include debuggers that can
trace the contents of various memory locations to help locate a logic error. However, do
not rely on the debugger alone to help correct the problem, but rather use it as a tool to
assist in tracing the logic of the program. If a debugger is not available, well-placed output
statements at critical points in the program can help in the debugging process. In the end,
it is the programmer reading the code carefully to see what the code is actually doing, rather
than what one thinks it is doing, that will ultimately fix logic errors in a program. [9]
testing and correct operation of a program is imperative and is the responsibility of the
programmers.
The field that includes these instances and other related issues is known as ethics. Entire
stand-alone courses are offered, typically from the philosophy department, and
corresponding books have been written that address the many theories and the application
of those theories to specific instances. In addition, these ethical theories have been
applied to paticular areas such as business ethics, medical ethics, environmental ethics as
well as computer ethics. With respect to the latter, many colleges offer separate courses
in computer ethics that may be given as an elective or may be required for a major in
computer science.
Since entire books have also been written on the field of computer ethics it would not be
possible to discuss all the theories here. Fortunately, various professional organizations in
many different fields provide codes of ethics. The same is true in the field of computing
where the Institute of Electrical and Electronics Engineers (IEEE) Computer Society[3]
and the Association of Computing Machinery (ACM) [1] have each developed a Code of
Ethics. These codes help provide guidance when confronting various ethical situations
within the world of computing.
These codes are provided by their respective organizations and are available online. The
reader is encouraged to look at least one of these codes as possLEO\LQGLFDWHGE\RQH¶V
instructor. It might also prove interesting to look at both codes to see the similarities and
possible differences between them.
After examining a code of ethics such as the ACM Code of Ethics, there are some
exercises at the end of the chapter based on the discussion at the beginning of this section
that can serve either as a discussion in the classroom or as an essay question in a
homework assignment. Although it is beyond the scope of this text to examine the
theories and codes in any detail, there are a number of texts that examine theories and
LVVXHVLQPRUHGHWDLOVXFKDV³(WKLFVLQ&RPSXWLQJ$&RQFLVH0RGXOH´E\-RVHSK0LJJD
Kizza. [5]
0.6 Summary
Machine language and assembly language are low-level languages, where the former
uses ones and zeros and the latter uses mnemonics.
High-level languages are more English-like, where C, C++, and Java are examples of
high-level languages.
Compilers convert the entire high-level language program into machine language
before executing the machine language program, whereas interpreters convert a high-
level language program one instruction at a time and then execute only the
corresponding machine language instructions before converting the next high-level
instruction.
Java is a hybrid system, where the Java instructions are converted into an intermediate
language called bytecode using a compiler and then the bytecode is converted into
machine language using an interpreter.
Computational thinking is a problem-solving process that includes decomposition,
pattern recognition, abstraction, algorithms, and logical thinking. The above are skills
that you can apply in life in general.
14 0 Introduction to Computing Concepts
3. Compare the two codes of ethics mentioned previously in Section 0.5. Identify
one or more elements that are similar. If possible, identify one element that
appears in one code but does not seem to appear in the other.
4. Using one of the code of ethics such as the ACM Code of Ethics, or the code
assigned by the instructor, analyze the following scenarios as to the proper course
of action. Be sure to indicate which element in the code applies.
a. A student in a first-year course has asked a fellow student for assistance with
their programming assignment. After starting to look over the program for the
SRWHQWLDOHUURUWKHVWXGHQWVHHNLQJDVVLVWDQFHVD\V³7KLVLVVXUHWDNLQJDORWRI
time. Might it be easier to just send me a copy of the file containing your
SURJUDPDQG,FDQMXVWFKDQJHWKHQDPHDWWKHWRS"´$FFRUGLQJWRWKHFRGHRI
ethics selected or assigned, what should the student who is providing the
assistance do? What alternatives are there?
Abstract
This chapter provides an initial skeleton program from which to create subsequent programs. An introduction
to variables, constants, assignment statements, arithmetic operations, and simple input/output using the
keyboard and monitor is also provided. Further, there is a discussion concerning comments and a simple
complete program is included at the end of the chapter.
Keywords
Input/Output, Variables, Assignment Statement, Arithmetic, Comments.
1.1 Introduction
This section introduces the reader to the basics of the Java programming language and
helps get the first program up and running as quickly as possible. To that end, the
explanation of some of the more complicated aspects of a Java program are deferred until
later. Many of the OOP (Object-Oriented Programming) concepts are only briefly
introduced, but will be discussed more thoroughly in Chapters 2, 5, and 9. For those who
want a more detailed discussion and elaboration of some of the concepts presented in this
chapter, it can be found in Appendix A. However, note that for some of the sections of
Appendix A, it helps to have read at least Chapters 2, 5, and possibly 9, or have had
previous OOP programming experience.
The first line in the program begins with the reserved word class. A reserved word is
one that has a special meaning in a program and cannot have its meaning changed by the
programmer nor can it be used for other purposes. As briefly discussed in Chapter 0, a class
is a definition of a group of objects. Although classes and objects will be discussed further
in Chap. 2 , for now think of a class as a blueprint for a house and the houses built from
the blueprint as objects.
The word Skeleton following the reserved word class, is the name of the class
that is provided by the programmer. This name is known as an identifier and the rules for
identifiers will be discussed in Section 1.4. Note that usually class names begin with a
capital letter. The entire definition of the class, Skeleton, should be placed between the
first opening brace and the last closing brace, { }.
This class has one method definition starting on the second line. A method is like a
function in mathematics which are sent values via arguments and can return a single value.
Typically, the body of the method is indented to improve the readability of the program.
The word main is the name of the method. When a program is run, the system will
search for the main method and start executing instructions in the main method. For now,
the rest of the words in this line will be discussed later throughout the text and in Appendix
A. The definition of the main method also starts with an opening brace and ends with a
closing brace. Inside the braces, a sequence of instructions would be placed. For now, the
method does not have any instructions and only contains a comment line.
Comments will not be compiled and executed when the program is run. They are used
to make programs easier for other programmers to understand. Comments can start with
// symbols and continue to the end of the line as shown in Figure 1.1, or be placed between
/* and */ symbols. The // symbols are used for a single-line comment, and /* and */
are used when the comments run over multiple lines. Comments are discussed more
thoroughly in Section 1.9, The above program should compile without any syntax errors
and run without any execution errors, except unfortunately it does not do anything.
³+HOOR:RUOG´
Unless a program performs some type of output, it is not particularly useful and it is
difficult to know whether the program has run. Output can be of many forms including
output to a screen, a printer, or a disk. In this section, only output to a screen will be
considered. Although there are several ways to output data to the screen, this section will
examine the simplest of them to get started.
1.3 “Hello World!” 19
One of the more common first programs written when learning a new language is the
LQIDPRXV³+HOOR:RUOG´SURJUDP7KHDGYDQWDJHRIWKLVSURJUDPLVWRPDNHVXUHWKDWRQH
is writing a program correctly and using the compiler properly. This program can be written
as shown in Fig. 1.2.
The program looks very similar to the original Skeleton program in Fig. 1.1, except
that the class name has been changed from Skeleton to Output and the comment line
has been replaced with the System.out.println("Hello World!"); statement.
This statement outputs the string contained within the double quotation marks to the
monitor. Java uses System.out to refer to the standard output device which by default
is the monitor. To perform output, one simply uses the println method to display a
primitive value or a string to the monitor. The println method is part of the Java
Application Programming Interface (API) which is a predefined set of classes that can be
used in any Java program. The classes and methods in the Java API provide a variety of
fundamental services that are not part of the language itself.
Go ahead and try typing in this program on your computer using the IDE (Integrated
Development Environment) installed in your lab, home computer, or place of employment
and then compile and execute the program. Provided there are no syntax errors, the output
should appear similar to the following, where the underscore represents the ending location
of the cursor on the screen:
Hello World!
_
Notice that the quotation marks are not output to the screen and the cursor appears on
the next line. Also note that the cursor might not appear on the screen, since there is no
input yet, but in this example, it serves to illustrate where any subsequent input or output
would appear.
20 1 Input/Output, Variables, and Arithmetic
Simple GUI based output to display a message dialog box can be accomplished by using
the showMessageDialog method as shown in Fig. 1.3.
import javax.swing.*;
class MsgBoxOutput {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Hello World!");
System.exit(0);
}
}
Also, notice that the last statement System.exit(0) causes the program to stop
executing since a program with JOptionPane does not automatically stop when the
end of the main method is reached. When the program above is executed a dialog box
shown below appears on the screen.
1.4 Variables and Constants 21
When the user clicks the OK button, the dialog box will close. Both types of output, text-
based and GUI-based, will be used throughout the text, with text-based used more
frequently due to its simplicity.
The address of the mailbox is usually a number, like the address of a memory location
in a computer. At the machine language level, the address is in ones and zeros, just like the
machine language instructions mentioned in Chapter 0. However, using numbers to
represent the address of a memory location can be quite confusing, especially if there are
hundreds of memory locations in a program. Instead, it is helpful to use characters to form
names, called symbolic addressing, to make it easier to remember what data is stored in
what memory location as shown in Fig. 1.5. In this example, the name number is used to
describe the contents of the corresponding memory location. This is one of the primary
advantages of using assembly language over machine language, and this is also true of all
high-level languages including Java.
Typically, the types int, double, char, and String are the ones that are used the
most frequently. For example, should one want to declare a variable named number and
have it store an integer, it would be declared as follows:
int number;
First the type is indicated, in this case int for integer, and then the identifier or name
of the variable number is given, followed by a semicolon. An identifier or the name of
the variable can be almost anything except for a reserved word as discussed in Section 1.2,
but there are certain rules that need to be followed as well as some suggestions that should
be followed. The length of the variable name can be from 1 to any number of characters
long. Further, the variable name can be composed of letters, numbers, underscores _, and
dollar signs $, but must begin with a letter. Also, the variable name is case sensitive,
meaning that cat, Cat, and CAT are separate variable names and correspond to separate
memory locations.
1.4 Variables and Constants 23
Typically, a variable name should not be too long, because they can be difficult to read,
but by the same token, they should not be too short either, for it could become difficult to
remember what it represents. For example, if the letter n were used instead of number,
then it might not be clear whether n stood for name, number, or numeral. Exceptions
to this are for variables from a mathematical expression. For example, the variables x, y,
and z are commonly used to represent the points of a Cartesian coordinate system, and i,
j, or k are used for loop control variables as will be discussed in Chap. 4 . Although most
of the time this text will avoid the use of shorter names, on occasion shorter names might
be used to save space or for the sake of simplicity to concentrate on other aspects of a code
segment. If a variable is too long, it can be difficult to read as in the following:
numberofcatsanddogs. Common practice in Java is not to capitalize the first letter of
a variable but to capitalize the first letter in all subsequent words, as in
numberOfCatsAndDogs. Notice that it is a little easier to read that way. Also on
occasion, abbreviations can be used such as num instead of number, but be sure to use
good ones. Further, this text will occasionally show some of the more commonly used
abreviations.
Variables of other types can be declared as well, such as a variable of type float or
double. Although numbers of type float WDNHXSOHVVVSDFHLQWKHFRPSXWHU¶VPHPRU\
they are less precise and can sometimes cause inaccuracy in calculations. Even though they
take up more memory, this text will use double variables to alleviate some possible
problems later. For example, should one want to declare a variable to hold a double
precision value, it would be declared as follows:
double average;
Further it could contain a value and would look like the following:
Notice that instead of showing the number zero as an integer, it is represented as a real
number with a decimal point, to indicate its type as a double.
All of the types given in Table 1.1, other than the String type, are known as primitive
data types, meaning that when they are declared, the memory needed to store the associated
data is allocated at that time. However, a String data type is a reference data type. When
a variable of type String is declared, the memory allocated is not used to store the data,
but rather only to store a reference to the data. String data types are unique in that although
they are technically objects, they can be used syntactically as if they were primitive data
types.
The first part of this text will use strings in a very limited capacity. An understanding
of strings is much easier once one has had an introduction to objects and practice with
objects, so a full description of how string objects are created and manipulated is presented
in Chap. 6 +RZHYHUIRUQRZWKLVWH[WZLOOUHSUHVHQWVWULQJV³DVLI´WKH\DUHSULPLWLYH
data types, and the following shows a character primitive data type and a simplified view
of the string data type. For example, a character and string could be declared as follows:
24 1 Input/Output, Variables, and Arithmetic
Note that the char data type is represented using single quotation marks and that the
String is represented using double quotation marks. Although a character could be
represented as a String of length one, it is usually better to use the char data type.
Further, there are also ways to extract a single char type from a String data type. Again,
a full description will be deferred until Chap. 6 .
In contrast to variables, a constant can be declared so that its value cannot be changed.
Although not nearly as useful as variables, constants have their place in a program when a
value does not need to be changed, nor should be changed. For example, if an integer N
needs to remain a 7, then it could be declared as follows, where the use of the reserved
word final indicates that N is a constant:
final int N = 7;
Typically, constant names are declared as all capital letters to help other programmers
distinguish them from variables. In another example, suppose a number like PI needs only
two digits after the decimal point, then it could be declared as follows:
final double PI = 3.14;
Although the use of a constant might not be readily apparent at this time, their use will
become clearer in subsequent examples after discussing assignment statements in the next
section.
Does this mean that all variables need to be initialized to some value? Not necessarily.
As will be seen, only those variables that need an initial value for subsequent processing
1.5 Assignment Statements 25
should be initialized. Initializing a variable to a value when it does not need to be initialized
could be confusing to other programmers reading the code, as will be discussed later in this
chapter and in Chap. 4 on iteration structures.
So, if a variable is assumed not to be initialized, how does one initialize a variable to a
value such as 0 or any other value for that matter, such as 5? After a variable is declared,
it can be given a value in an assignment statement using an assignment symbol. The
assignment symbol is the equal sign. However, when one first starts to use the equal sign,
RQHPXVWUHPHPEHUWKDWLWGRHVQRWPHDQWKDWWKHYDULDEOHRQWKHOHIWLV³HTXDOWR´WKHYDOXH
on the right, but rather that the value on the right is copied into or assigned to the variable
on the left. Again, this is best shown by way of an example:
int number;
number = 5;
After the variable number is declared as type int, the second statement indicates that
the integer 5 is assigned or copied into the variable number and the memory location
would then appear as follows where green indicates a change:
number 5
Again, the assignment statement is not really saying that number is equal to 5 or equals
5, but rather that the variable number is assigned a 5 or takes on the value of 5. Although
it is tempting to say that number equals 5 and even though most people will understand
what is meant, try to avoid saying it, and there will be less difficulty in the future as shown
in Sect. 1.8 on arithmetic statements.
Note that it is possible to combine the previous two statements into one statement as
shown below. It looks similar to the definition of a constant in the previous section but
without the word final in the statement:
int number = 5;
The above syntax is perfectly legal and saves a line when writing a program. However,
when first learning a language, it helps to reinforce the distinction between the declaration
of a variable and the assignment of a YDOXHWRDYDULDEOH2IFRXUVHLIRQH¶VLQVWUXFWRUGRHV
not mind the above shortcut or if one is studying this text on their own and likes the
shortcut, then go ahead and use it. However, this text will use the previous two-line method
at least for the next few chapters to help reinforce the distinction between the declaration
of a variable and the assignment of a value to a variable.
Continuing, what if one wanted to take the contents of number, and copy it into another
memory location named answer? For example, consider the following code segment:
The third line then takes a copy of the contents of number and places it into the
memory location answer as shown below:
number 5 answer 5
Note that the assignment statement does not remove the 5 from number and put it into
answer, but rather it takes a copy of the 5 and puts it into answer. The original 5 in
number does not disappear. Why does it copy and not move it? The reason is because it
is actually faster for the computer to copy it and not take the time to delete the original.
This is a fundamental concept in most computer languages and will become more important
in the writing of subsequent programs.
Again, the important point to notice is that the copying of values is from right to left,
not left to right. This sometimes causes confusion among beginning programmers, possibly
because they are used to reading from left to right. The reason why Java and many previous
languages go from right to left is because they are mimicking some of the assembly
languages on many machines. Ideally it would be nice if languages used an arrow to show
how values are copied as shown below:
However, most keyboards do not have an arrow character, so an equal sign was used.
Just be very careful to remember that values are copied from right to left and there should
not be any problems.
Assigning variables of type double is similar to the above and will not be shown here;
however, a couple of points need to be made concerning assigning variables of different
types. For example, what would happen if a variable of type int was assigned to a variable
of type double as shown below?
int number;
double result;
number = 5;
result = number;
As before, the contents of the memory locations after the assignment of 5 to number
would be as follows:
Then when the next assignment statement is executed, the int value of 5 would be
1.5 Assignment Statements 27
Would the value in number be converted to a 5.0? The answer is no, as shown above,
because only the variable to the left of the assignment symbol is altered by an assignment
statement. The 5 in number is not converted, but rather when it is copied, it is converted
to the proper type so that it can be assigned to result.
If an int value can be stored in a variable of type double, is the reverse true? The
answer is no, because, for example, how could the number 5.7 be stored as an integer
without the fractional part? A way around this problem is to use a typecast operator. A
typecast operator allows a value of one type to be converted to another type. In the case
below, the typecast operator (int) converts the double value in number to type int
so it can be assigned to result. As before, the value in number would not change and
would still contain a 5.7. However, what happens to the fractional part? The result is that
it is truncated and a 5 is stored in result:
double number;
int result;
number = 5.7;
result = (int) number;
What if the value needed to be rounded instead? Fortunately, Java has the Math class
which contains a method named round. As mentioned previously, a method is somewhat
like a function in mathematics. The name of the class, Math, is followed by a period and
the name of the method, round. Parentheses are placed after the method name and contain
the argument, number, which is sent to the method. The code segment from above is
rewritten below:
double number;
int result;
number = 5.7;
result = (int) Math.round(number);
Unfortunately, when the round method is sent a value of type double, it returns a
value of type long, but the typecast operator (int) can again be used to convert the
value of type long to type int. Since number initially contains 5.7, the variable
result would contain a 6. Again, the value in number would not change and would still
contain a 5.7.
Of course, if the precision of the type double is needed, the better solution would be
to change the type of result to double to preserve the fractional part of number. The
28 1 Input/Output, Variables, and Arithmetic
round method is one of the many methods available in the Math class which is discussed
in more detail in Sect. 1.8 on arithmetic statements.
1.6 Output
1.6.1 Text-based
Recall from Section 1.3 that the following:
System.out.println("Hello World!");
output the following:
Hello World!
_
where the cursor appeared on the next line. However, what if one wanted to split the string
so that it appears on two separate lines? This can be accomplished by using two separate
System.out.println statements as follows:
System.out.println("Hello");
System.out.println("World!");
As one might suspect, the output would appear as follows:
Hello
World!
_
The string "Hello" is output and the cursor moves down to the next line. Then, the
string "World!" is output, and again the cursor moves down to the next line in
preparation for the subsequent line to be output.
In another example, what if one wanted to output the following with a blank line
between the two words and the cursor at the bottom?
Hello
World!
_
The first statement outputs the word Hello and moves the cursor down to the second
line. The second statement does not output anything, so the ln of the
System.out.println statement causes the cursor to move down to the third line and
the blank line to appear on output. Lastly, the word World! is output and the cursor moves
1.6 Output 29
down to the fourth line. Note that usually a System.out.println() indicates that a
blank line will be output, but there are exceptions that are discussed further in Appendix
A.
Although the above is useful for outputting strings and vertically formatting output, how
does one output integers and real numbers? Combining the information learned in the
previous two sections, one can then have a program as shown in Fig. 1.6.
This program declares the variable num to be of type int, assigns the value 5 to num,
and then outputs the contents of the variable num. Note that the variable num is not
enclosed in quotation marks, so the word num is not output, but rather the contents of the
variable num are output. Unfortunately, only the integer 5 would be output to the screen
which would not be very useful. Instead, it is helpful to output some other information for
the user to identify and understand the information on the screen.
The output statement in the program in Fig. 1.6 can be modified to include the string
"The number is " followed by a plus sign prior to the variable num as shown in Fig.
1.7. A plus sign between two strings or between a string and any other type of data means
concatenation. In other words, the string "The number is " and the contents of num
are output as if they are one string. It should be noted that one needs to be careful should
only two integers be separated by a plus sign, because then it would mean addition as will
be discussed in Sect.1.8. However, provided a string or a concatenated string appears to the
left, then the item to the right of the plus sign will be concatenated instead of added. Note
that there is a space within the quotes at the end of the string so that the contents of the
variable num are separated from the word is in the string. The result is that the output of
this program would appear as follows:
The number is 5
_
What happens if one outputs a number of type double using the same format shown
in Fig. 1.7? For example, Fig.1.8 outputs the contents of the variable num of type double.
As will be discussed further in Sect.1.8, the / means division and num will take on the
value of one third. When the above program is compiled and executed, the screen displays
The number is 0.3333333333333333
Although using high precision is necessary during computation, it may not be needed
when a number of type double is displayed. How can one limit the number of digits after
the decimal point in a floating-point number? A predefined method in the Java API called
printf can be used. The general syntax of the printf method is as follows:
where control string is a string that may consist of substrings and format specifiers
and an expr represents a variable, expression, or constant value. A format specifier
indicates how an expr should be displayed. A specifier %d is used for a decimal integer,
%f for a floating-point number, %c for a character, and %s for a string. For numbers, the
total width and precision can be indicated in a specifier. For example, the specifier %10d
outputs an integer value with a width of at least 10. The specifier %10.2f outputs a
floating-point number with a width of at least 10 including a decimal point and two digits
after the decimal point. The width of character and string values can also be indicated. For
example, the specifier %3c outputs a single character and adds two spaces before it, and
%10s outputs a string with a width at least 10 characters. If there is more than one expr
to be output, they must match the specifiers within the control string in order, number, and
type. Using the formatting information described above, the program in Fig. 1.8 can be
rewritten as in Fig. 1.9.
Waverley.
The trees were once more clothed in their wonted green after the
passing of a northern winter. The woods and fields were enameled in
a thousand colors, and the birds were raising their cheerful voices to
greet the spring of the year 1759. All Nature smiled; only man
seemed sorrowful and cast down; and the laborer no more lifted his
gay song, and the greater portion of the lands lay fallow for lack of
hands to till them. A cloud hung over all New France, for the mother
country, a veritable step-mother, had abandoned her Canadian
children. Left to its own resources, the Government had called to
arms every able-bodied man to defend the colony against the
invasion that menaced it. The English had made vast preparations.
Their fleet, consisting of twenty ships of the line, ten frigates, and
eighteen smaller vessels, accompanied by a number of transports,
and carrying eighteen thousand men, was ascending the St.
Lawrence under the command of General Wolfe; while two land
armies, yet more numerous, were moving to effect a junction under
the very walls of Quebec.
The whole adult population of Canada capable of bearing arms
had responded with ardor to their country's appeal; and there
remained at home none but the old and feeble, the women and the
children. To resist an army more numerous than the entire
population of New France the Canadians had little but the memory
of past exploits, and of their glorious victory at Carillon in the
preceding year. Of what avail their proved courage against an enemy
so overpowering and sworn to their defeat?
You have long been misunderstood, my brethren of old Canada!
Most cruelly have you been slandered. Honor to them who have
lifted your memory from the dust! Honor, a hundred times honor, to
our fellow-countryman, M. Garneau, who has rent the veil that
covered your exploits! Shame to us who, instead of searching the
ancient and glorious annals of our race, were content to bow before
the reproach that we were a conquered people! Shame to us who
were almost ashamed to call ourselves Canadians! Dreading to
confess ourselves ignorant of the history of Assyrians, Medes, and
Persians, that of our own country remained a sealed book to us.
Within the last few years there has come a glorious reaction.
Every one sets his hand to the work and the Canadian can now say
with Francis I, "All is lost save honor." I am far from believing,
however, that all is lost. The cession of Canada was, perhaps, a
blessing in disguise; for the horrors of '93 failed to touch this
fortunate colony which was protected by the flag of Britain. We have
gathered new laurels, fighting beneath the banner of England; and
twice has the colony been saved to England by the courage of her
new subjects. In Parliament, at the bar, upon the field of battle,
everywhere in his small sphere, the French Canadian has proved
himself inferior to none. For a century have you struggled, O my
countrymen, to preserve your nationality, and you behold it yet
intact. The future perhaps holds for you another century of effort