Repository navigation
Expand file tree
/
Copy pathch4_conditionals.ptx
More file actions
615 lines (558 loc) · 28 KB
/
Copy pathch4_conditionals.ptx
File metadata and controls
615 lines (558 loc) · 28 KB
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
<?xml version="1.0"?>
<!-- Generated by Docutils 0.19 -->
<chapter xml:id="conditionals">
<title>Conditionals</title>
<section xml:id="simple-if">
<title>Using the Simple <c>if</c> Statement</title>
<p><idx>conditional statements</idx>
Conditional statements in Python and Java are very similar.
In Python we have three patterns:
</p>
<p>
In Python the simple <c>if</c> statement is written as:
</p>
<program xml:id="python-simple-if" interactive="activecode" language="python">
<code>
score = 95
if score >= 90:
print("Excellent work!")
</code>
</program>
<p>
In Java, this same pattern requires two changes: the condition must be in parentheses <c>()</c>, and the code block must be enclosed in curly braces <c>{}</c>.
</p>
<program xml:id="java-simple-if" interactive="activecode" language="java">
<code>
public class SimpleIfExample {
public static void main(String[] args) {
int score = 70;
if (score <= 70) {
System.out.println("Needs work!");
}
}
}
</code>
</program>
<p>
Once again you can see that in Java the curly braces define a block rather than indentation.
In Java, the parentheses around the condition are required because it is technically a function that evaluates to <c>True</c> or <c>False</c>.
</p>
</section>
<section xml:id="use-the-if-else-statement">
<title>Using the <c>if</c> - <c>else</c> Statement</title>
<p>The Java equivalent follows the same syntactical rules as before.</p>
<program xml:id="python-if-else" interactive="activecode" language="python">
<code>
age = 16
if age >= 18:
print("You can vote.")
else:
print("You are not yet eligible to vote.")
</code>
</program>
<program xml:id="java-if-else" language="java">
<code>
public class IfElseExample {
public static void main(String[] args) {
int age = 16;
if (age >= 18) {
System.out.println("You can vote.");
} else {
System.out.println("You are not yet eligible to vote.");
}
}
}
</code>
</program>
</section>
<section xml:id="elif">
<title>Can we use <c>elif</c>?</title>
<p><idx><c>elif</c> statement</idx>
Java does not have an <c>elif</c> pattern like Python.
In Java you can get the functionality of an <c>elif</c> statement by nesting <c>if</c> and <c>else</c>.
Here is a simple example in both Python and Java.
</p>
<program xml:id="python-if-nesting" interactive="activecode" language="python">
<code>
grade = int(input('enter a grade'))
if grade < 60:
print('F')
elif grade < 70:
print('D')
elif grade < 80:
print('C')
elif grade < 90:
print('B')
else:
print('A')
</code> <tests> </tests>
</program>
<p>
In Java, we have a couple of ways to write this.
</p>
<program xml:id="java-ifnesting" interactive="activecode" language="java">
<code>
public class ElseIf {
public static void main(String args[]) {
int grade = 85;
if (grade < 60) {
System.out.println('F');
} else {
if (grade < 70) {
System.out.println('D');
} else {
if (grade < 80) {
System.out.println('C');
} else {
if (grade < 90) {
System.out.println('B');
} else {
System.out.println('A');
}
}
}
}
}
}
</code> <tests> </tests>
</program>
<p>
We can get even closer to the <c>elif</c> statement by taking advantage of the Java rule that a single statement does not need to be enclosed in curly braces. Since the <c>if</c> is the only statement used in each <c>else</c> block, we can get away with the following.
</p>
<program xml:id="java-if-else-no-nesting" interactive="activecode" language="java">
<code>
public class ElseIf {
public static void main(String args[]) {
int grade = 85;
if (grade < 60) {
System.out.println('F');
} else if (grade < 70) {
System.out.println('D');
} else if (grade < 80) {
System.out.println('C');
} else if (grade < 90) {
System.out.println('B');
} else System.out.println('A');
}
}
</code> <tests> </tests>
</program>
</section>
<section xml:id="switch">
<title>Using the <c>switch</c> Statement</title>
<p>
Java also supports a <c>switch</c> statement that acts something like the <c>elif</c> or Python <c>match</c> statement under certain conditions. To write the grade program using a <c>switch</c> statement we would use the following:
</p>
<note>
<p>
The <c>match - case</c> statement was introduced in Python 3.10, so doesn't run in earlier version of Python. Here is an example using Python's <c>match - case</c> structure.
</p></note>
<program xml:id="python-match" language="python">
<title>Match Case Example</title>
<code>
grade = 85
# Convert grade to a scale of 0-10 using integer division
tempgrade = grade // 10
def grading(tempgrade):
match grade:
case 10 | 9:
return 'A'
case 8:
return 'B'
case 7:
return 'C'
case 6:
return 'D'
case _:
return 'F'
print(grading(tempgrade))
</code>
</program>
<p><idx><c>switch</c></idx>
The <c>switch</c> statement in Java provides an alternative to chaining multiple <c>if-else</c> conditions, when comparing a single variable against several constant values. It supports a variety of data types, including primitive types (<c>byte</c>, <c>short</c>, <c>char</c>, <c>int</c>), their wrapper classes, <c>enumerations</c>, and <c>String</c> (introduced in Java 7). Each <c>case</c> within a <c>switch</c> must be defined using a constant expression, and duplicate <c>case</c> values are not permitted. By default, control flow "<c>falls through</c>" from one <c>case</c> to the next unless a <c>break</c>, <c>return</c>, or <c>throw</c> statement is used to terminate execution.
</p>
<p>
<idx><c>switch</c> expressions</idx>
<idx><c>yield</c></idx>
Java 14 introduced <c>switch</c> <term>expressions</term>, enhancing functionality by allowing the <c>switch</c> to return values and eliminating <c>fall-through</c> via the <c>-></c> arrow syntax. These expressions can even use <c>yield</c> within code blocks for more complex evaluations. <term><c>yield</c></term> is used inside a switch expression’s block to produce the value of that expression, unlike <c>break</c> which simply exits a switch statement or loop. It’s important to note that traditional <c>switch</c> statements do not support <c>null</c> values and will throw a <c>NullPointerException</c> if evaluated with <c>null</c>. As the language evolves, newer versions of Java continue to extend <c>switch</c> capabilities with features like <c>pattern matching</c> and enhanced <c>type handling</c>, making it a more powerful and expressive tool for decision-making in Java programs.
</p>
<program xml:id="java-switch-up" interactive="activecode" language="java">
<code>
public class SwitchUp {
public static void main(String args[]) {
int grade = 85;
// Convert grade to a scale of 0-10 using integer division
int tempgrade = grade / 10;
switch(tempgrade) {
case 10:
case 9:
System.out.println('A');
break;
case 8:
System.out.println('B');
break;
case 7:
System.out.println('C');
break;
case 6:
System.out.println('A');
break;
default:
System.out.println('F');
}
}
}
</code> <tests> </tests>
</program>
<p>
The <c>switch</c> statement is not used very often, and we recommend you do not use it. First, it is not as powerful as the <c>else if</c> model because the switch variable can only be compared for equality with an integer or enumerated constant. Second, it is very easy to forget to put in the <c>break</c> statement, so it is more error-prone. If the break statement is left out then then the next alternative will be automatically executed. For example, if the grade was 95 and the <c>break</c> was omitted from the <c>case 9:</c> alternative then the program would print(out both A and B.)
</p>
<p>
Finally, the <c>switch</c> statement does not support relational expressions such as greater than or less than. So you cannot use it to completely replace the <c>elif</c>. Even with the new features of Java 14+ the <c>switch</c> statement is still limited to constant comparisons using equality.</p>
</section>
<section xml:id="exception-handling">
<title>Exception Handling</title>
<p>
In Python, if you want a program to continue running when an error has occurred, you can use <c>try-except</c> blocks to handle exceptions. If you wanted to write a program that asks the user to enter a whole number and then squares that number, you could use the following code to do so:
</p>
<program xml:id="python-square-input" interactive="activecode" language="python">
<code>
number = int(input("Please enter a whole number: "))
squared = number ** 2
print("Your number squared is " + str(squared))
</code>
</program>
<p>
The Java code that would perform the same task is a little more complex and utilizes the <c>Scanner</c> class for input.
</p>
<program xml:id="java-square-input" interactive="activecode" language="java">
<code>
import java.util.Scanner;
public class SquareNumber {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
System.out.print("Please enter a whole number: ");
int number = user_input.nextInt();
int squared = number * number;
System.out.println("Your number squared is " + squared);
}
}
</code>
</program>
<p>
This code works well, but will end with an exception if the user types anything other than a whole number (such as 12.5 or two). If we wanted to ensure the code will continue to run until the user enters the correct format, we could add <c>try-except</c> (Python) or <c>try-catch</c> (Java) blocks within a <c>while</c> loop that iterates until the user enter the correct code. Adding <c>try-except</c> blocks and a <c>while</c> loop to the Python code will look something like this:
</p>
<program xml:id="python-square-input-exception" interactive="activecode" language="python">
<code>
while True:
try:
number = int(input("Please enter a whole number: "))
squared = number ** 2
print("Your number squared is " + str(squared))
break
except ValueError:
print("That was not a valid number. Please try again: ")
</code>
</program>
<p>
Now that we have Python code that will continuously prompt the user until they enter a whole number, let's look at Java code that accomplishes the same task. Like most other equivalent Java code blocks, this code has a lot of extra bits that are necessary to get working code.
</p>
<program xml:id="java-square-input-exception" interactive="activecode" language="java">
<code>
import java.util.Scanner;
import java.util.InputMismatchException;
public class SquareNumberWithValidation {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
try {
System.out.print("Please enter a whole number: ");
int number = scanner.nextInt();
int squared = number * number;
System.out.println("Your number squared is " + squared);
break;
} catch (InputMismatchException e) {
System.out.println("That was not a valid number. Please try again: ");
scanner.nextLine(); // Clear the invalid input from the scanner
}
}
}
}
</code> <stdin> </stdin> <tests> </tests>
</program>
<p>
Firstly, let's talk about the extra import alongside the <c>Scanner</c> import. In Java, we need to import <c>InputMismatchException</c> because it's not automatically available like basic exceptions. This is different from Python where most exceptions are readily accessible. If you ran the previous Java codeblock without <c>try-catch</c> blocks and entered an erroneous input, you would have got an <c>InputMismatchException</c> exception despite not having imported this class. That being said, removing the explicit import of this library for the <c>try-catch</c> code block above will lead to compilation errors.
</p>
<p>
<idx>checked exception</idx>
<idx>unchecked exception</idx>
Exceptions in Java fall under two categories: checked and unchecked. <term>Checked exceptions</term> must be explicitly imported and declared along with <c>try-catch</c> blocks for a program to compile. <term>Unchecked exceptions</term> do not need to be imported unless <c>try-catch</c> blocks are implemented for them (except for <c>java.lang</c> exceptions). <c>InputMismatchException</c> is an unchecked exception that is not part of the <c>java.lang</c> library, so it is only included if <c>try-catch</c> blocks declare it. Here are some common exceptions used with <c>try-catch</c> blocks:
</p>
<table>
<title>Exceptions</title>
<tabular>
<row>
<cell><term>Exception</term></cell>
<cell><term>Package</term></cell>
<cell><term>Description</term></cell>
</row>
<row>
<cell><c>IOException</c></cell>
<cell><c>java.io</c></cell>
<cell>Thrown when an I/O operation fails (e.g., reading or writing a file).</cell>
</row>
<row>
<cell><c>FileNotFoundException</c></cell>
<cell><c>java.io</c></cell>
<cell>Thrown when an attempt to open a file denoted by a pathname has failed.</cell>
</row>
<row>
<cell><c>ParseException</c></cell>
<cell><c>java.text</c></cell>
<cell>Thrown when parsing a string into a date, number, etc. fails (e.g., wrong format).</cell>
</row>
<row>
<cell><c>NoSuchMethodException</c></cell>
<cell><c>java.lang</c></cell>
<cell>Thrown when a particular method cannot be found via reflection.</cell>
</row>
<row>
<cell><c>InputMismatchException</c></cell>
<cell><c>java.util</c></cell>
<cell>Thrown when <c>Scanner</c> input doesn’t match the expected data type.</cell>
</row>
<row>
<cell><c>SQLException</c></cell>
<cell><c>java.sql</c></cell>
<cell>Thrown when a database access error occurs (e.g., invalid SQL query, bad connection).</cell>
</row>
<row>
<cell><c>InstantiationException</c></cell>
<cell><c>java.lang</c></cell>
<cell>Thrown when trying to create an instance of an abstract class or interface.</cell>
</row>
<row>
<cell><c>IllegalAccessException</c></cell>
<cell><c>java.lang</c></cell>
<cell>Thrown when a reflection operation tries to access a field or method it doesn't have permission for.</cell>
</row>
</tabular>
</table>
<p>
Note that as with other structures in Java, <c>try-catch</c> blocks blocks must be encased with braces <c>{}</c>. The most important part of this code is, after <c>catch</c>, there is a set of parenthesis with an exception type and a variable name <c>catch (InputMismatchException e)</c>. This is where we declare a <c>InputMismatchException</c> exception and name it with the variable name <c>e</c>. It is common practice, though not a requirement, to name exception variables <c>e</c> in this manner.
</p>
</section>
<section xml:id="ternary-operator">
<title>The Ternary Operator</title>
<p><idx>Boolean operators</idx> <idx>simple comparisons</idx> <idx>compound Boolean expressions</idx>
The conditionals used in the if statement can be <term>Boolean variables</term>, <term>simple comparisons</term>, and <term>compound Boolean expressions</term>.
</p>
<p><idx>ternary operator</idx>
Java also provides the ternary operator <c>condition ? valueIfTrue : valueIfFalse</c>, which lets you use a <c>boolean</c> test directly inside an assignment. If the condition is true, the first value is chosen; otherwise, the second value is used. The table below summarizes how it works:
</p>
<table>
<title>Ternary Operator in Java</title>
<tabular>
<row>
<cell><term>Component</term></cell>
<cell><term>Description</term></cell>
</row>
<row>
<cell><c>condition</c></cell>
<cell>The <c>boolean</c> expression that is evaluated (e.g., <c>a % 2 == 0</c>).</cell>
</row>
<row>
<cell><c>?</c></cell>
<cell> This is the ternary operator that separates the condition from the <c>trueValue</c>.</cell>
</row>
<row>
<cell><c>trueValue</c></cell>
<cell>The value assigned if the condition is true (e.g., <c>a * a</c>).</cell>
</row>
<row>
<cell><c>:</c></cell>
<cell> This is the ternary operator that separates the <c>trueValue</c> from the <c>falseValue</c>.</cell>
</row>
<row>
<cell><c>falseValue</c></cell>
<cell>The value assigned if the condition is false (e.g., <c>3 * x - 1</c>).</cell>
</row>
<row>
<cell>Example Usage</cell>
<cell><c>a = a % 2 == 0 ? a * a : 3 * x - 1</c></cell>
</row>
<row>
<cell>Equivalent if-else Code</cell>
<cell>Can also be written with a regular <c>if-else</c> statement, but the ternary form is more concise.</cell>
</row>
</tabular>
</table>
<p>
Using this operator can make code shorter and more readable in cases where a simple conditional assignment is needed. See the following as an example where we see the same logic implemented in two different ways.
</p>
<program xml:id="java-ternary" interactive="activecode" language ="java">
<code>
public class Ternary {
public static void main(String[] args) {
int a = 4;
int x = 2;
int outp;
// ternary:
outp = (a % 2 == 0) ? (a * a) : (3 * x - 1);
System.out.println("ternary result: " + outp);
// Equivalent using if/else
if (a % 2 == 0) {
outp = a * a;
} else {
outp = 3 * x - 1;
}
System.out.println("if/else result: " + outp);
}
}
</code>
</program>
<p>
In this example we are using this ternary operator to assign a value to <c>a</c> based on whether <c>a</c> is even or odd. If <c>a</c> is even, it will be squared; if odd, it will be instead be calculated as <c>3 * x - 1</c>. This is a concise way to write conditional assignments in Java. However, you might want to use it sparingly, as it can make code less readable if overused or used with complex expressions.
</p>
</section>
<section xml:id="chapter4_summary">
<title>Summary & Reading Questions</title>
<p><ol label="1">
<li>
<p>Java requires parentheses around the condition and curly braces for code blocks in <c>if</c> statements, unlike Python which uses indentation alone.</p>
</li>
<li>
<p>Java uses <c>else if</c> instead of Python's <c>elif</c>, and allows optional curly braces for single-line blocks. However, it is considered good practice to use curly braces even for single-line blocks to improve readability.</p>
</li>
<li>
<p>
Java's <c>switch</c> statement is similar to Python's <c>match</c> statement, but it only supports equality checks against constant values and does not evaluate relational expressions like greater than or less than.
</p>
</li>
<li>
<p>
Java uses the <c>boolean</c> data type to represent logical values <c>true</c> or <c>false</c>, commonly used in conditionals and control flow.
</p>
</li>
</ol></p>
<reading-questions xml:id="rqs-summary4">
<exercise label="summary-if-parentheses">
<statement>
<p>Which is a correct Java <c>if</c> statement syntax?</p>
</statement>
<choices>
<choice correct="yes">
<statement>
<p>if (x > 0) { System.out.println("Positive"); }</p>
</statement>
<feedback>
<p>Correct! Java requires parentheses and curly braces.</p>
</feedback>
</choice>
<choice>
<statement>
<p>if x > 0: print("Positive")</p>
</statement>
<feedback>
<p>No, that's Python syntax, not Java.</p>
</feedback>
</choice>
<choice>
<statement>
<p>if x > 0 { System.out.println("Positive"); }</p>
</statement>
<feedback>
<p>No, Java requires parentheses around the condition.</p>
</feedback>
</choice>
<choice>
<statement>
<p>if (x > 0) print("Positive");</p>
</statement>
<feedback>
<p>No, <c>print</c> is not a valid method in Java. Use <c>System.out.println</c>.</p>
</feedback>
</choice>
</choices>
</exercise>
<exercise label="summary-else-if">
<statement>
<p>How do you write Python’s <c>elif</c> equivalent in Java?</p>
</statement>
<choices>
<choice>
<statement>
<p>elif (score > 90)</p>
</statement>
<feedback>
<p>No, <c>elif</c> is used in Python, not Java.</p>
</feedback>
</choice>
<choice>
<statement>
<p>else: if (score > 90)</p>
</statement>
<feedback>
<p>Incorrect syntax; no colon in Java and not the right structure.</p>
</feedback>
</choice>
<choice correct="yes">
<statement>
<p>else if (score > 90)</p>
</statement>
<feedback>
<p>Right! Java uses <c>else if</c>.</p>
</feedback>
</choice>
<choice>
<statement>
<p>ifelse (score > 90)</p>
</statement>
<feedback>
<p>No, <c>ifelse</c> is not a valid construct in Java.</p>
</feedback>
</choice>
</choices>
</exercise>
<exercise label="summary-switch-limitation">
<statement>
<p>What is one limitation of Java's <c>switch</c> statement, including in its modern versions?</p>
</statement>
<choices>
<choice>
<statement>
<p>It cannot evaluate relational expressions like greater than or less than.</p>
</statement>
<feedback>
<p>No, while <c>switch</c> can compare values, it does not support relational expressions like <c>></c> or <c><</c>, even with modern enhancements of Java 14+</p>
</feedback>
</choice>
<choice>
<statement>
<p>It cannot handle more than five case labels.</p>
</statement>
<feedback>
<p>No, there is no such limit. You can have many case labels in a <c>switch</c> statement.</p>
</feedback>
</choice>
<choice>
<statement>
<p>It always requires a <c>break</c> statement.</p>
</statement>
<feedback>
<p>Incorrect. The <c>break</c> statement is actually an optional feature of <c>switch</c>, not a limitation.</p>
</feedback>
</choice>
<choice correct="yes">
<statement>
<p>It can only compare a variable to constant values using equality.</p>
</statement>
<feedback>
<p>Correct! Java's <c>switch</c> is limited to constant comparisons using equality.</p>
</feedback>
</choice>
</choices>
</exercise>
</reading-questions>
</section>
</chapter>