Decisions, decisions, decisions Chapter 3 Spring 2007 CS 101 Aaron Bloomfield 1 Background Our problem-solving solutions so far have the straight-line property They execute the same statements for every run of the program public class DisplayForecast // main(): application entry point public static void main(String[] args) { System.out.print("I think there is a world"); System.out.print(" market for maybe five "); System.out.println("computers. “); System.out.print(" Thomas Watson, IBM, “); System.out.println("1943.“); } } 2 Background For general problem solving we need more capabilities The ability to control which statements are executed The ability to control how often a statement is executed We will concentrate first on controlling which statements are executed Java provides the if and switch conditional constructs to control whether a statement list is executed The if constructs use logical expressions to determine their course of action We will start with logical expressions 3 Logical expressions 4 Logical expressions The branch of mathematics dealing with logical expressions is Boolean algebra Developed by the British mathematician George Boole 5 Logical expressions A logical expression has either the value logical true or logical false Some expressions whose values are logical true The year 2004 is a leap year A meter equals 100 centimeters Some expressions whose values are logical false A triangle has four sides The area of square is always equal to twice its perimeter 6 Logical expressions There are three primary logical operators for manipulating logical values Logical and Logical or Logical not The operators work as most of us would expect 7 Truth tables We use truth tables to give formal specifications of the operators “It works as most of us would expect” allows for ambiguity of interpretation Jim is smiling or Patty is smiling Can both Jim and Patty both be smiling? Truth tables Lists all combinations of operand values and the result of the operation for each combination p q p and q False False True True False True False True False False False True 8 Or and not truth tables p q False False True True False True False True p or q False True True True p False True not p True False 9 Boolean algebra Can create complex logical expressions by combining simple logical expressions not (p and q) p q p and q not (p and q) False False True True False True False True False False False True True True True False 10 DeMorgan’s laws not (p and q) equals (not p) or (not q) p False False True True q False True False True p and q False False False True (not p) or not (p and q) ( not p) (not q) (not q) True True True False True True True False False True False False True True True False 11 DeMorgan’s laws not (p or q) equals (not p) and (not q) p False False True True q False True False True p or q False True True True not (p or q) True False False False (not p) and ( not p) (not q) (not q) True True True False False True False False True False False False 12 DeMorgan’s laws If you remember nothing else about the Boolean operators, remember that: not (a and b) == (not a) or (not b) not (a or b) == (not a) and (not b) 13 Sidewalk chalk guy Source: http://www.gprime.net/images/sidewalkchalkguy/ 14 Boolean expressions 15 A boolean type Java has the logical type boolean Type boolean has two literal constants true false Operators The and operator is && Don’t use & The or operator is || Don’t use | The not operator is ! 16 Defining boolean variables Local boolean variables are uninitialized by default boolean isWhitespace; boolean receivedAcknowledgement; boolean haveFoundMissingLink; isWhitespace - receivedAcknowledgement - haveFoundMissingLink - 17 Defining boolean variables Local boolean variables with initialization boolean canProceed = true; boolean preferCyan = false; boolean completedSecretMission = true; canProceed true preferCyan false completedSecretMission true 18 Assignment vs. comparison = is the assignment operator It copies the value on the right to the location on the left Consider: int x; x = 5; The value 5 is copied to the spot x in memory == is the comparison operator Returns a boolean (true or false) if the two sides are equal Consider: int x = 5; System.out.println (x == 5); System.out.println (x == 6); 19 Prints out true, false Other operators Equality operators == and != Operator == Returns true if the operands have the same value; otherwise, returns false This is not the assignment operator! Operator != Returns true if the operands have different values; otherwise, returns false The operators work with all types of values 20 Evaluating boolean expressions Suppose boolean boolean boolean boolean p = true; q = false; r = true; s = false; What is the value of p !s q p && r q || s p && s p == q q != r r == s q != s 21 Evaluating boolean expressions Suppose int i = 1; int j = 2; int k = 2; char c = '#'; char d = '%'; char e = '#'; What is the value of j == k i == j c == e c == d i != k j != k d != e c != e 22 These images are not animated… 23 Translating English to logical expressions 25 Translating English to logical expressions English doesn’t always translate cleanly into logical expressions To see this, we need to examine the NOR operator It doesn’t exist in Java, but we can fake it p NOR q == NOT (p OR q) NOR is represented by a downward arrow: p False False True True q False True False True p or q False True True True not (p or q) True False False False In Java, given variables p and q NOR is done by: !(p||q) p nor q True False False False 26 Translation Example “I have neither given nor received help on this exam” Rephrased: “I have not given nor received …” Let p = “I have given help on this exam” Let q = “I have received help on this exam” Translation is: pq Remember the precedence: NOT is done first! p q p pq T T F F T F F T F T T F F F T F 27 Translation example, take 2 “I have neither given nor received help on this exam” Rephrased: “I have not (given nor received …)” Let p = “I have given help on this exam” Let q = “I have received help on this exam” Another translation is: (pq) = p || q p q p || q T T T T F T F T T F F F 28 Translation example, rephrased What is meant is “I have not given and I have not received help on this exam” Or “I have not (given or received) help on this exam” This is a DeMorgaization of the one above it p q pq (p||q) T T F F T F F F F T F F F F T T The problem: has a higher precedence than in Boolean logic, but not always in English Also, “neither” is vague 29 Disclaimer The preceding example was showing that when English can be clear, it does not always translate clearly into Boolean logic The English meaning is exact The Boolean translation is not This does not mean that you can cheat, and say that I said it was allowed by the honor code 30 Floating point comparison 31 Floating point precission What gets printed? class FloatTest { public static void main (String args[]) { double y = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1; System.out.println (y); } } There are 10 0.1’s 32 Program demo FloatTest.java 33 Take care with floating-point values Consider double a = 1; double b = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1; double c = .9999999999999999; Two true expressions! c == b b != a Two false expressions! a == b b != c Problem lies with the finite precision of the floating-point types Instead with the ordering operators for closeness 34 How to solve this Don’t compare floating-point values if you can help it! Both doubles and floats Need to test if the two doubles are “close” in value final double EPSILON = 0.000001; boolean foo = Math.abs (a-b) < EPSILON; 35 Sand Castles 36 More on evaluating expressions 37 Ordering operators Java provides ordering operators for the primitive types Four ordering operators, <, >, <=, and >= They correspond to mathematical operators of <, >, ≤, and ≥ Together the equality and ordering operators are known as the relational operators False is less than true 38 Evaluation boolean expressions Suppose int i = 1; int j = 2; int k = 2; What is the value of i<j j<k i <= k j >= k i >= k 39 Unicode values Character comparisons are based on their Unicode values Characters ‘0’, ‘1’, … ‘9’ have expected order Character ‘0’ has the encoding 48 Character ‘1’ has the encoding 49, and so on. Upper case Latin letters ‘A’, ‘B’, … ‘Z’ have expected order Character ‘A’ has the encoding 65, character ‘B’ has the encoding 66, and so on. Lower case Latin letters ‘a’, ‘b’, … ‘z’ have expected order Character ‘a’ has the encoding 97 Character ‘b’ has the encoding 98, and so on. 40 Evaluation boolean expressions Suppose char c = '2'; char d = '3'; char e = '2'; What c c c d c is the value of < d < e <= e >= e >= e 41 Operator precedence revisited Highest to lowest Parentheses Unary operators Multiplicative operators Additive operators Relational ordering Relational equality Logical and Logical or Assignment 42 Expressions vs. statements A statement is a single command for Java to do, and always ends in a semi-colon (for now, at least) System.out.println (“hello world”); int x = 4; ++x; An expression returns a value, and does not have a semicolon 5 circle.getRadius() x Note the difference between the following: ++i is an expression ++i; is a statement 43 New 2005 demotivatiors! 44 if statement 45 Conditional constructs Provide Ability to control whether a statement list is executed Two constructs If statement if if-else if-else-if Switch statement 46 Basic if statement Syntax if (Expression) Action If the Expression is true then execute Action Action is either a single statement or a group of statements within braces Expression true false Action For us, it will always be a group of statements within braces 47 Example if (value < 0) { value = -value; } Is our number negative? If Value is less than zero then we need to update its value to that of its additive inverse Value < 0 true Value = -Value Our number is now definitely nonnegative false If Value is not less than zero then our number is fine as is 48 Sorting two values System.out.print("Enter an integer number: "); int value1 = stdin.nextInt(); System.out.print("Enter another integer number: "); int value2 = stdin.nextInt(); // rearrange numbers if necessary if (value2 < value1) { // values are not in sorted order int rememberValue1 = value1; value1 = value2; value2 = rememberValue1; } // display values What happens if the user enters 11 and 28? What happens if the user enters 11 and 4? System.out.println("The numbers in sorted order are " + value1 + " and then " + value2); 49 Are the numbers out of order If semantics Rearrange value1 and value2 to put their values in the proper order value2 < value1 true false int rememberValue1 = value1 value1 = value2 value2 = rememberValue1 The numbers were rearranged into the proper order The numbers were initially in order The numbers are in order What an if statement executes An if statement executes the next block of code A block is either: A single statement without curly brackets: if (a == b) System.out.println (“a==b!!!”); A number of statements enclosed by curly brackets: if (a == b) { System.out.print (“a”); System.out.print (“==”); System.out.print (“b”); System.out.println (“!!!”); } 51 Why we always use braces What is the output? int m = 5; int n = 10; if (m < n) ++m; ++n; System.out.println(" m = " + m + " n = “ + n); 52 Warn your grandparents! Historically, this class has been lethal to grandparents of students in the class – More often grandmothers This happens most around test time – Although occasionally around the times a big assignment is due See http://www.cis.gsu.edu/~dstraub/Courses/Grandma.htm53 if-else statement 54 The if-else statement Syntax if (Expression) Action1 else Action2 If Expression is execute Action1 execute Action2 Expression true then otherwise The actions are either a single statement or a list of statements within braces true false Action1 Action2 55 Finding the maximum of two values System.out.print("Enter an integer number: "); int value1 = stdin.nextInt(); System.out.print("Enter another integer number: "); int value2 = stdin.nextInt(); But is it initialized? int maximum; if (value1 < value2) { // is value2 larger? maximum = value2; // yes: value2 is larger } else { // (value1 >= value2) maximum = value1; // no: value2 is not larger } System.out.println("The maximum of " + value1 + " and " + value2 + " is " + maximum); 56 Finding the maximum of two values System.out.print("Enter an integer number: "); int value1 = stdin.nextInt(); System.out.print("Enter another integer number: "); int value2 = stdin.nextInt(); int maximum; if (value1 < value2) { maximum = value2; } But is it initialized? // is value2 larger? // yes: value2 is larger System.out.println("The maximum of " + value1 + " and " + value2 + " is " + maximum); 57 Finding the maximum of two values Is value2 larger than value1 Yes, it is . So value2 is larger than value1. In this case, maximum is set to value2 value1 < value2 true maximum = value2 Either case, maximum is set correctly No, its not. So value1 is at least as large as value2. In this case, maximum is set to value1 false maximum = value1 58 Why we use whitespace What does the following do? System.out.print("Enter an integer number: "); int value1 = stdin.nextInt(); System.out.print("Enter another integer number: "); int value2 = stdin.nextInt(); if (value2 < value1) { int rememberValue1 = value1; value1 = value2; value2 = rememberValue1; } System.out.println("The numbers in sorted order are " + value1 + " and then " + value2); 59 How do you like your braces? if (a == b) { //... } else { //... } if (a == b) { //... } else { //... } if (a == b) { //... } else { //... } if (a == b) { //... } else { //... } if (a == b) { //... } else { //... } 61 If-then-else precedence if (number != 0) if (number > 0) System.out.println("positive"); Which if does this else else refer to? System.out.println("negative"); 62 If-then-else precedence without whitespace if (number != 0) if (number > 0) System.out.println("positive"); else System.out.println("negative"); else System.out.println("zero"); 63 Program demo ElsePrecedence.java 64 Becoming an IEEE author 65 if-else-if statement 66 If-else-if Consider if (number == 0) { System.out.println("zero"); } else { if (number > 0) { We can change the whitespace of the code These braces aren’t needed System.out.println("positive"); } } else { System.out.println("negative"); }Same results as previous segment – but this segment better expresses the meaning of what is going on 67 Sorting three values For sorting values n1, n2, and n3 there are six possible orderings n1 n2 n3 n1 n3 n2 n2 n1 n3 n2 n3 n1 n3 n1 n2 n3 n2 n1 Suppose s1, s2, s3 are to be a sorted version of n1, n2, and n3 68 Sorting three values if ((n1 <= n2) && (n2 <= n3)) s1 = n1; s2 = n2; s3 = } else if ((n1 <= n3) && (n3 <= s1 = n1; s2 = n3; s3 = } else if ((n2 <= n1) && (n1 <= s1 = n2; s2 = n1; s3 = } else if ((n2 <= n3) && (n3 <= s1 = n2; s2 = n3; s3 = } else if ((n3 <= n1) && (n1 <= s1 = n3; s2 = n1; s3 = } else { // n3 <= n2 <= n1 s1 = n3; s2 = n2; s3 = } { n3; // n1 <= n2 <= n3 n2)) { // n1 <= n3 <= n2 n2; n3)) { // n2 <= n1 <= n3 n3; n1)) { // n2 <= n3 <= n1 n1; n2)) { // n3 <= n1 <= n2 n2; n1; 69 ?: notation 70 Finding the minimum value Consider: // z is to hold the minimum of x and y if ( x < y ) z = x; Notice no braces! else z = y; Another way to do this: z = (x<y) ? x : y; 71 The ?: notation Only works when both “cases” return a value! Meaning when both “cases” are expressions Example: z = (x<y) ? x : y; Thus, you can’t put a print statement in there! Can be difficult to read System.out.println ((number != 0) ? ((number > 0) ? "positive“ : "negative") : "zero“); if (number != 0) if (number > 0) System.out.println("positive"); else System.out.println("negative"); else System.out.println("zero"); 72 A bit of humor… 73 switch statement 74 Switch statement Software engineers often confronted with programming tasks where required action depends on the values of integer expressions The if-else-if construct can be used Separately compare the desired expression to a particular value If the expression and value are equal, then perform the appropriate action Because such programming tasks occur frequently Java includes a switch statement The task is often more readable with the switch then with the if-else-if 75 A switch statement example if (a == ‘0’) System.out.println else if (a == ‘1’) System.out.println else if (a == ‘2’) System.out.println else if (a == ‘3’) System.out.println else if (a == ‘4’) System.out.println else System.out.println (“zero”); (“one”); (“two”); (“three”); (“four”); (“five+”); switch (a) { case ‘0’: System.out.println break; case ‘1’: System.out.println break; case ‘2’: System.out.println break; case ‘3’: System.out.println break; case ‘4’: System.out.println break; default: System.out.println break; (“zero”); (“one”); (“two”); (“three”); (“four”); (“five+”); 76 Switch statement Integral expression to be matched with a case expression switch ( SwitchExpression ) case CaseExpression1 : Action1 ; case CaseExpression2 : Action2 ; Java statements { Constant integral expression ... case CaseExpressionn : Actionn ; default : } Actionn+1 ; 78 Testing for vowel-ness switch case case case case case case case case case case } (ch) { 'a': 'A': 'e': 'E': 'i': 'I': 'o': 'O': 'u': 'U': System.out.println("vowel“); break; default: System.out.println("not a vowel“); 79 Testing for vowel-ness switch (ch) { case 'a': case 'A': case 'e': case 'E': case 'i': case 'I': case 'o': case 'O': case 'u': case 'U': System.out.println("vowel“); break; The break causes an exiting of the switch default: System.out.println("not a vowel“); } Handles all of the other cases 80 A better way to format that switch statement switch (ch) { case 'a': // FALL case 'A': // FALL case 'e': // FALL case 'E': // FALL case 'i': // FALL case 'I': // FALL ... THRU THRU THRU THRU THRU THRU 81 Processing a request System.out.print("Enter a number: "); int n1 = stdin.nextInt(); System.out.print("Enter another number: "); int n2 = stdin.nextInt(); System.out.print("Enter desired operator: "); char operator = stdin.nextLine().charAt(0); switch (operator) { case '+' : System.out.println((n1 + n2)); break; case '-' : System.out.println(n1 - n2); break; case '*' : System.out.println(n1 * n2); break; case '/' : System.out.println(n1 / n2); break; default: System.out.println(“Illegal request“); } 82 How well do you feel you understand the swtich statement? 1. Very well! This stuff is easy! 2. Fairly well – with a little review, I’ll be good 3. Okay. It’s not great, but it’s not horrible, either 4. Not well. I’m kinda confused 5. Not at all. I’m soooooo lost oo ... so oo c. .. I’m ll. N ot at a w el l. ot N da ki n I’m no It’ s y. ka O ,b u. .. tg re at a ith w w el l– irl y Fa Ve ry w el l! Th is st uf fi ... lit t.. 20% 20% 20% 20% 20% 83 Biggest software errors Ariane 5 rocket explosion (1996) – Due to loss of precision converting 64-bit double to 16-bit int Pentium division error (1994) – Due to incomplete look-up table (like an array) Patriot-Scud missile error (1991) – Rounding error on the time – The missile did not intercept an incoming Scud missile, leaving 28 dead and 98 wounded Mars Climate Orbiter (1999) – Onboard used metric units; ground computer used English units AT&T long distance (1990) – Wrong break statement in C code Therac-25, X-ray (1975-1987) – Badly designed software led to radiation overdose in chemotherapy patients NE US power blackout (2003) – Flaw in GE software contributed to it References: http://www5.in.tum.de/~huckle/bugse.html, http://en.wikipedia.org/wiki/Computer_bug, http://www.cs.tau.ac.il/~nachumd/verify/horror.html 84 Object equality 85 Testing variables for equality Consider System.out.print("Enter an integer number: "); int n1 = stdin.nextInt(); System.out.print("Enter another integer number: "); int n2 = stdin.nextInt(); if (n1 == n2) { System.out.println("Same"); } else { System.out.println(“Different"); } What is the output if the user enters 88 and 3? What is the output if the user enters 88 both times? 86 Program Demo IntEquality 87 Testing objects for equality Consider String s1 = “pastel”; String s2 = s1; if (s1 == s2) { System.out.println("Same"); } else { System.out.println("Different"); } 88 Testing objects for equality Memory looks like s1 "pastel" s2 The comparison is between the references! Thus, s1 and s2 are the same (they refer to the same object) 89 Testing objects for equality Consider System.out.print("Enter a string: "); String s1 = stdin.nextLine(); System.out.print("Enter another string: "); String s2 = stdin.nextLine(); if (s1 == s2) { System.out.println("Same"); } else { System.out.println("Different"); } What is the output if the user enters "pastel" both times? 90 Program Demo StringEquality 91 Testing objects for equality When it is executed System.out.print("Enter a string: "); String s1 = stdin.nextLine(); System.out.print("Enter another string: "); String s2 = stdin.nextLine(); Memory looks like s1 "pastel" s2 "pastel" As a result no matter what is entered s1 and s2 are not the same 92 They refer to different objects Comparing strings for equality Consider: String u = new String("hello"); String v = new String("hello"); System.out.println (u == v); What gets printed? These aren’t the false exact same thing Consider: String s = "hello"; String t = "hello"; System.out.println (s == t); What gets printed? true Huh? 93 Program Demo StringEquality2 94 Testing operators for equality Consider System.out.print("Enter a string: "); String s1 = stdin.nextLine(); System.out.print("Enter another string: "); String s2 = stdin.nextLine(); Tests whether s1 and s2 represent the same object if (s1.equals(s2)) { System.out.println("Same"); } else { System.out.println("Different"); } Most classes have a method equals(). It compares the objects themselves, not the references. 95 Today’s demotivators 96 Short-circuit evaluation 97 Short-circuit evaluation The value of a logical expression can be known before all the operands have been considered If left operand of && is false, then the value must be false If left operand of || is true, then the value must be true Java uses these properties to make logical operations efficient Evaluates left operand before it evaluates right operand If the operator value is determined from the left operand, then the right operand is not evaluated The operation is short-circuited 98 Short-circuit evaluation Short-circuit evaluation is useful when some property must be true for some other expression to be evaluated Suppose you are interested in knowing whether scoreSum divided by nbrScores is greater than value The condition can be evaluated only if nbrScores is nonzero The following expression correctly represents the condition (nbrScores != 0) && ((scoreSum / nbrScores) > value) 99 Short-circuit evaluation Output returnsFalse() called Assume we have a returnsFalse() method from a ‘foo’ object It returns false And it prints “returnsFalse() called” And a returnsTrue() method Consider: if } if } if } if } returnsTrue() called returnsFalse() called returnsFalse() called returnsTrue() called returnsTrue() called ( foo.returnsFalse() && foo.returnsTrue() ) { ( foo.returnsTrue() && foo.returnsFalse() ) { ( foo.returnsFalse() || foo.returnsTrue() ) { ( foo.returnsTrue() || foo.returnsFalse() ) { 100 How well do you feel you understand decision statements (ifs, switches) in Java? 1. Very well! This stuff is easy! 2. Fairly well – with a little review, I’ll be good 3. Okay. It’s not great, but it’s not horrible, either 4. Not well. I’m kinda confused 5. Not at all. I’m soooooo lost oo ... so oo c. .. I’m ll. N ot at a w el l. ot N da ki n I’m no It’ s y. ka O ,b u. .. tg re at a ith w w el l– irl y Fa Ve ry w el l! Th is st uf fi ... lit t.. 20% 20% 20% 20% 20% 101