forked from sergutsan/groovyck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsection5-doWhile,switch,ternary.tex
290 lines (230 loc) · 9.54 KB
/
section5-doWhile,switch,ternary.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
\section{More on branches}
\label{sec:more-branches-loops}
You can write a lot of different programs with the little
\texttt{if\ldots else} and \texttt{while} constructs you have already
learned and practiced, for executing different branches in your
program and for running loops. There are, however, other constructs
that you can use to make your programs clearer. In this section we
will learn about the \texttt{do\ldots while} loops, the
\texttt{switch\ldots case} multiple branching feature, and the
so-called ternary operator. In later chapters, we will also see how to
use the very useful \texttt{for} and \emph{for each} loops.
\subsection{Multiple branching}
\label{sec:multiple-branching}
Look at the following code, that loosely resembles an automatic
phone-answering program:
\VerbatimInput[frame=single,label=Example]{src/s5E1.groovy}
Such a long list of \texttt{if} branches can be a bit confusing for
future readers. When there are many options, and especially if the
options are finite and known in advance, it is better to make the
multiple branching clearer by using a \texttt{switch\ldots case}
construct, as in the following example:
\VerbatimInput[frame=single,label=Example]{src/s5E2.groovy}
As you can see, the multiple branches are introduced by the keyword
\texttt{switch} followed by some parameter, \emph{choice} in this
case. Then several possible cases follow, each of them starting by a
semicolon. The whole list of cases is inside two curly brackets, but
the code of each case does not need curly brackets.
There are two important things to note in this program. First, there
is a keyword \texttt{break} at the end of each case. This is very
important. Without it, Groovy will finish the execution of one case
and continue with the next one. Second, there is a default case that
is executed if none of the other cases matches \emph{choice}. This is
also important: always write a default case for your
\texttt{switch\ldots case} structures. They are good for detecting
errors in your program.
\subsubsection*{Exercise A}
Write a program like the one in the last example, but add a little
code for each case (some \texttt{println} statements will do) and
remove the \texttt{break} keywords. Execute the program and see what
happens.
\subsubsection*{Exercise B}
Write a program similar to the one in the former example, but a bit
better. Make the computer ask for an option and then execute the
corresponding code in a \texttt{switch\ldots case} structure. If the
user introduces an invalid option (e.g. 9 in the example above), make
the computer say ``That is not a valid option, please try again'', and
ask again until the user enters a valid numbers. Hint: You will need
to use a loop and change the default case.
\subsubsection*{Exercise C}
Write a program that uses Strings instead of integers for the
\texttt{switch}. What happens?
\subsubsection{What types can go inside a \texttt{switch}}
\label{sec:what-types-can}
If you have tried all the exercises above, you have noticed that
Groovy complains when you try to use Strings inside a
\texttt{switch\ldots case}. The bad news is that we cannot use any
type of data, but only things like integers, characters (also known as
\emph{chars} for brevity), and enumerated types (also known as
\emph{enums}, we will come to them in a second). The good news is that
this is usually enough.
Characters can be used alone in any Groovy program, can be printed on
the screen, and can also be
combined to form our well-known Strings, as in the following code:
\VerbatimInput[frame=single,label=Example]{src/s5E3.groovy}
Notice that single quotes are used for characters and double quotes
are used for Strings: \'c\' is the character \emph{c}, but ``c'' is a
String with only the character \emph{c} in it.
\subsubsection{What are \emph{enums}}
\label{sec:what-types-enum}
Enumerated types are just lists of \emph{tags} that can be useful to
make your program more legible. They can be used to specify constants
that have some special meaning. Defining an \emph{enum} in Groovy is
really easy:
\begin{verbatim}
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY,
}
\end{verbatim}
Now, this new enum can be used in \texttt{switch} (or \texttt{if})
statements. Compare the clarity of this code:
\begin{verbatim}
switch (day) {
case 1:
// do something here for this day
break;
case 3:
// do something here for this day
break;
...
}
\end{verbatim}
and this code:
\begin{verbatim}
switch (day) {
case MONDAY:
// do something here for this day
break;
case WEDNESDAY:
// do something here for this day
break;
...
}
\end{verbatim}
In the second case, it is clear what each case is for. In the first
piece of code, you need to guess: look at the code for each case, look
at the surrounding code\ldots it is harder. Programming is already a
hard (and fun) activity. It is wise not to make it harder than it is;
it does not make it any funnier.
There is a general lesson to learn here. What you see in the code
above is an example of \emph{magic numbers}: numbers that appear in
your code and have an effect, but is difficult to understand what
their effect is or why they are what they are (i.e. why a~1~and not
a~5?). \textbf{Magic number make code harder to read and
understand. Never use magic numbers in your code.}
\subsection{The ternary operator}
\label{sec:ternary-operator}
There is another form of writing a branch. It is not commonly used,
but you should know it exists. It is the so-called \emph{ternary
operator}.
Most operators in Groovy are either \emph{unary} (they take one
argument, like logical NOT~``!'') or \emph{binary} (they take two
arguments, like logical AND~``\&\&'' or addition~``+''). There is only
one ternary operator, with three arguments, that is really another
fancy way of writing an \texttt{if\ldots else} clause. We will
illustrate how it works with a simple example:
\begin{verbatim}
print "Enter a number: "
int i = Integer.parseInt(System.console().readLine())
String s = (i > 5)? "Greater than 5" : "Not greater than 5"
println s
\end{verbatim}
This code behaves exactly in the same as the following code:
\begin{verbatim}
print "Enter a number: "
int i = Integer.parseInt(System.console().readLine())
String s;
if (i > 5) {
s = "Greater than 5"
} else {
s = "Not greater than 5"
}
println s
\end{verbatim}
As you see, the ternary operator takes three arguments: a boolean
expression and two values. If the boolean expression is true, then the
second argument is returned; if it is false, it returns the third
argument.
In some cases the ternary operator can make your code clearer, but
these cases are few and far between. In general, it is easier to write
\emph{bona fide} \texttt{if} statements. However, you may find the
ternary operator in code written by others, and it is thus important
to understand how it works.
\subsubsection*{Exercise D}
Write a program that reads a series of numbers from the user, until the
user enters the String ``END''. The program
should then print how many numbers were positive, negative, or
zero. Write the program using (a) \texttt{if\ldots else} clauses first
and then using (b) the ternary operator.
Is there any difference? In which case it is
easier to write the program? In which case does it look clearer to you?
\subsection{It's a kind of magic}
\label{sec:its-kind-magic}
The ternary operator is not the only strange way of making your code
shorter. Incremental operations are so common that combinations of
symbols are used ---in a slightly cryptic way--- to make those code
lines shorter.
Incremental lines are lines in which the value of a variable
(typically \verb+int+) is incremented by some explicit value or the
value of another variable, for example:
\begin{verbatim}
time = time + lap;
depth = depth + drillDepth;
\end{verbatim}
This can be written in a shorter way like:
\begin{verbatim}
time += lap;
depth += drillDepth;
\end{verbatim}
The same principle can be applied to most binary operators, including
subtraction, multiplication, division, and string concatenation; so:
\begin{verbatim}
record = record - difference;
result = result * 2;
name = name + newTitle;
\end{verbatim}
become:
\begin{verbatim}
record -= difference;
result *= 2;
name += newTitle;
\end{verbatim}
A particular example is the increment of integer variable by one or
minus, used for all sorts of counters:
\begin{verbatim}
time = time + 1;
count = count + 1;
i = i + 1;
timesLeft = timesLeft - 1;
\end{verbatim}
which are most often written much more shortly as:
\begin{verbatim}
time++;
++count;
i++;
timesLeft--;
\end{verbatim}
There is a small difference between the line \verb-i++- and the line
\verb-++i-. The former evaluates the statement and then increases the
value of \verb+i+ while the later increases the value of \verb+i+ and
then evaluates the statement. This a subtle difference that you should
now worry about and should actually avoid in modern code. In other
words: never write any code that would behave differently if you
changes all instances of \verb-i++- for \verb-++i+. This is very easy
to do by just following the following rule:
\begin{center}
\vspace{1em}
\textbf{\large If you use i++ or similar, make sure it is the only
thing you write in that statement; do not combine it with anything else. }
\vspace{1em}
\end{center}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "main"
%%% End: