The IF Revisited A few more things Copyright © 1998-2016 Curt Hill
Now what? There are several more issues that need consideration Pictures Conditions Nesting Testing Handle comparisons If problems Copyright © 1998-2016 Curt Hill
Files TurtleGraphic file handing has two places where an if should be used The return of pickAFile The return of write Lets consider these first Copyright © 1998-2016 Curt Hill
pickAFile The pickAFile method returns a handle to a string What happens if the user hit cancel or the kill button? pickAFile then returns a null A null is a handle that points at nothing Thus you should always check it: String fn = FileChooser.pickAFile(); if(fn != null) p = new Picture(fn); Copyright © 1998-2016 Curt Hill
Commentary In the previous example the Picture could not be declared in the if The else of the if needs to prevent any further processing Or do something like this: String fn = FileChooser.pickAFile(); if(fn == null) return; Picture p = new Picture(fn); Copyright © 1998-2016 Curt Hill
The write method The write returns a Boolean This can be used in an if: if(!p.write(filename)) System.out.writeln( “Error writing”); Notice there is no comparison with the output of the write A Boolean is already a true/false value Copyright © 1998-2016 Curt Hill
Conditions We would like to determine if a value is between two bounds It looks good but does not work The precedence makes it this: if((1 < a) < 10) The first parenthesis produces a boolean which cannot be compared with an int Thus we must do: if(1 < a && a < 10) Copyright © 1998-2016 Curt Hill
Nesting Any statement may be the THEN or ELSE statement of an if It is most often a compound statement The interesting one is an if in an if The usual problem is how the elses match the ifs Copyright © 1998-2016 Curt Hill
Which else? The else may only match one of these Which one is it? The answer is 3! if(a>b) // 1 if(b>c) // 2 if(c>d)// 3 x = y; else x = z; Copyright © 1998-2016 Curt Hill
Matching Elses The general rule is that an else matches the closest, previous, unmatched if The language ignores white space and also the layout on the page Thus indenting has no relevance to the compiler It may make the program more (or less) readable Copyright © 1998-2016 Curt Hill
A Matched Else How is an if matched? An else is encountered for it It is enclosed within a compound statement An unrelated statement follows Copyright © 1998-2016 Curt Hill
Three examples if(a>b) // 1 if(b>c) // 2 if(c>d)// 3 x = y; else x = 2*y; else // matches 2 x = z; if(a>b) // 1 if(b>c){ // 2 if(c>d)// 3 x = y; } else // matches 2 x = z; if(a>b) // 1 x = y; y = x*z; else // error x = z; Copyright © 1998-2016 Curt Hill
Comparison of Objects Comparison (==) is based on the handle not the value If equality is true then two handles are the same This is a weaker condition than the two values the same The two values may represent two heap memory items with same value and not compare equal Copyright © 1998-2016 Curt Hill
Comparison Example Consider: String s = “Hi”, t = “Hi”; Compiler will generally recognize that the two strings are same and only store one copy Thus s==t will be true However there are situations where we are not so lucky Copyright © 1998-2016 Curt Hill
Unequal Comparison Consider String s = “Hi”; String t = “Hi there”,u; u = s + “ there”; Generally t == u will be false The runtime system does not store the two strings as one Copyright © 1998-2016 Curt Hill
Unequal Comparisons Again String s = “Hi”; String t = “Hi there”,u; u = s + “ there”; s Hi t Hi there u Hi there Copyright © 1998-2016 Curt Hill
Equals The equals method is used to determine if the values on the heap are equal It is more reliable when it is implemented Not every object implements it String and StringBuffer do Thus use s.equals(t) instead of s==t Copyright © 1998-2016 Curt Hill
Testing Ifs complicate our testing With only sequential flow we test it once and it is covered With multiple paths one test is generally inadequate Testing strategies then come into view Copyright © 1998-2016 Curt Hill
Every Statement The first strategy is to make sure that in our testing every statement is tested once We generate test data accordingly We have enough test data each if has both its then and else exercised once This usually means several runs Copyright © 1998-2016 Curt Hill
Every statement if(a>b) { // 1 b = a++ * 2; c /= 2; } else // 2 1 2 c = a * b / 2; 1 2 Two tests are needed. One forces a > b and the other a <= b Copyright © 1998-2016 Curt Hill
A path is a unique way through the code There are four paths 1 2 1, 3 2, 3 1, 4 3 4 2, 4 Copyright © 1998-2016 Curt Hill
Test Data Again In the above, every statement testing only needs two runs The paths {1,3} and {2,4} executes every statement However, there may be interactions between 1 and 4 that are not exercised Thus every path testing is always as good or better than every statement In programs without decisions or loops one set does both Copyright © 1998-2016 Curt Hill
How ifs increase paths An if added at the end of a sequence doubles the number of paths An if nested within an if adds one path to the existing number The generalities do not always capture the actual practice Reconsider the quadratic formula evaluation Copyright © 1998-2016 Curt Hill
Two different approaches if(discrim < 0) … else if(discrim == 0){ … } else { if(discrim < 0){ … } if(discrim == 0){ … } if(discrim > 0){ Copyright © 1998-2016 Curt Hill
Commentary on above The nested if version is to be preferred If any of the conditions is true then no further ones will be checked Typically check the most likely one first rather than the straight order I used However, provided that discrim is not changed in the ifs both have three paths Copyright © 1998-2016 Curt Hill
Largest of three variables Here are two ways to display the largest of three variables, a, b and c if(a>b) if(a>c) term.println(a); else term.println(c); else if(b>c) term.println(b); term.println(c); double big; big = a; if(big<b) big =b; if(big<c) big = c; term.println(big); Which do you like better? Why? Copyright © 1998-2016 Curt Hill
Comparison The first one has two comparisons and one write The second one has two comparisons, one to three assignments, one write and needs one temporary variable Both have four paths Most professional programmers like the second one Easier to categorize where you are Copyright © 1998-2016 Curt Hill
Paths and Complexity More paths cause more complexity Complexity promotes errors As programmers we work hard to subdivide the problem to manage the complexity The magic number is 7 ± 2 TMI and cockpit stories Copyright © 1998-2016 Curt Hill