CSS161: Fundamentals of Computing Debugging This slide set was compiled from the Absolute Java textbook slides (Walter Savitch) and the professor’s own class materials. CSS161: Fundamentals of Computing
CSS161: Fundamentals of Computing Loop Bugs Infinite Loops Off-by-one error: one too many or one too few loops Solution Use <= or >= Use integer variables for ( int count = 0; count != 9; count += 2 ) { // loop body } public class OffByOne { public static void main( String[] args ) { double count; for ( count = 0.1; count <= 0.3; count += 0.1 ) System.out.println( "count = " + count ); System.out.println( "last count = " + count ); } [mfukuda@perseus css161]$ java OffByOne count = 0.1 count = 0.2 last count = 0.30000000000000004 CSS161: Fundamentals of Computing
CSS161: Fundamentals of Computing Tracing Variables Calculate the sum of 1 through to 10 Output public class Sum10 { public static void main( String[] args ) { int n = 10; int sum = 10; while ( n > 1 ) { System.out.println( "loop begin: n = " + n + ", sum = " + sum ); sum = sum + n; n--; System.out.println( "loop end: n = " + n + ", sum = " + sum ); } System.out.println( "The sum of the integers 1 to 10 is " + sum ); [mfukuda@perseus css161]$ java Sum10 loop begin: n = 10, sum = 10 loop end: n = 9, sum = 20 loop begin: n = 9, sum = 20 loop end: n = 8, sum = 29 loop begin: n = 8, sum = 29 loop end: n = 7, sum = 37 loop begin: n = 7, sum = 37 loop end: n = 6, sum = 44 loop begin: n = 6, sum = 44 loop end: n = 5, sum = 50 loop begin: n = 5, sum = 50 loop end: n = 4, sum = 55 loop begin: n = 4, sum = 55 loop end: n = 3, sum = 59 loop begin: n = 3, sum = 59 loop end: n = 2, sum = 62 loop begin: n = 2, sum = 62 loop end: n = 1, sum = 64 The sum of the integers 1 to 10 is 64 [mfukuda@perseus css161]$ java Sum10 loop begin: n = 10, sum = 10 loop end: n = 9, sum = 19 loop begin: n = 9, sum = 19 loop end: n = 8, sum = 27 loop begin: n = 8, sum = 27 loop end: n = 7, sum = 34 loop begin: n = 7, sum = 34 loop end: n = 6, sum = 40 loop begin: n = 6, sum = 40 loop end: n = 5, sum = 45 loop begin: n = 5, sum = 45 loop end: n = 4, sum = 49 loop begin: n = 4, sum = 49 loop end: n = 3, sum = 52 loop begin: n = 3, sum = 52 loop end: n = 2, sum = 54 loop begin: n = 2, sum = 54 loop end: n = 1, sum = 55 The sum of the integers 1 to 10 is 55 CSS161: Fundamentals of Computing
General Debugging Techniques Examine the system as a whole – don’t assume the bug occurs in one particular place Try different test cases and check the input values Comment out blocks of code to narrow down the offending code Check common pitfalls Take a break and come back later DO NOT make random changes just hoping that the change will fix the problem! CSS161: Fundamentals of Computing
Debugging Example (1 of 10) Code to get a user input until either ‘a’ or ‘b’ is entered. Compilation error: import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s.toLowerCase( ); c = s.substring( 0, 1 ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ javac DebugExample.java DebugExample.java:13: incompatible types found : java.lang.String required: char c = s.substring( 0, 1 ); ^ 1 error CSS161: Fundamentals of Computing
Debugging Example (2 of 10) Use the “random change” technique to the date type of c to String: Receive more errors: import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; String c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s.toLowerCase( ); c = s.substring( 0, 1 ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ javac DebugExample.java DebugExample.java:6: incompatible types found : char required: java.lang.String String c = ' '; ^ DebugExample.java:15: incomparable types: java.lang.String and char while ( ( c != 'a' ) || ( c != 'b' ) ); 3 errors CSS161: Fundamentals of Computing
Debugging Example (3 of 10) Compiler errors eliminated by s.charAt( 0 ) The program now stuck in an infinite loop import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s.toLowerCase( ); c = s.charAt( 0 ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ javac DebugExample.java [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. C B A (Control-C) CSS161: Fundamentals of Computing
Debugging Example (4 of 10) Employ tracing variables. String S is never changed to lowercase. import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); System.out.println( "String s = " + s ); s.toLowerCase( ); System.out.println( "Lowercase s = " + s ); c = s.charAt( 0 ); System.out.println( "c = " + c ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. A String s = A Lowercase s = A c = A CSS161: Fundamentals of Computing
Debugging Example (5 of 10) toLowerCase( ) returns a lowercase string While c can now receives ‘a’ or ‘b’, the program can’t get out of the loop. do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); System.out.println( "String s = " + s ); s = s.toLowerCase( ); System.out.println( "Lowercase s = " + s ); c = s.charAt( 0 ); System.out.println( "c = " + c ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. A String s = A Lowercase s = a c = a B String s = B Lowercase s = b c = b CSS161: Fundamentals of Computing
Debugging Example (6 of 10) The following patch works but makes the Boolean expression meaningless. import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); System.out.println( "String s = " + s ); s = s.toLowerCase( ); System.out.println( "Lowercase s = " + s ); c = s.charAt( 0 ); System.out.println( "c = " + c ); if ( c == 'a' ) break; if ( c == 'c' ) } while ( ( c != 'a' ) || ( c != 'b' ) ); Then, this could be while ( true ) [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. A String s = A Lowercase s = a c = a [mfukuda@perseus css161]$ CSS161: Fundamentals of Computing
Debugging Example (7 of 10) Dissect the Boolean expression || is always true! public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s = s.toLowerCase( ); c = s.charAt( 0 ); System.out.println( "c = " + c ); System.out.println( "c != 'a' is " + ( c != 'a' ) ); System.out.println( "c != 'b' is " + ( c != 'b' ) ); System.out.println( "( c != 'a' ) || ( c != 'b' ) is " + ( ( c != 'a' ) || ( c != 'b' ) ) ); } while ( ( c != 'a' ) || ( c != 'b' ) ); [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. A c = a c != 'a' is false c != 'b' is true ( c != 'a' ) || ( c != 'b' ) is true CSS161: Fundamentals of Computing
Debugging Example (8 of 10) Recall the || and && operators’ truth table LHS (c != ‘a’) RHS (c != ‘b’) || (c != ‘a’) || (c != ‘b’) && (c != ‘a’) && (c != ‘b’) False True CSS161: Fundamentals of Computing
Debugging Example (9 of 10) Replace || with && Get a correct result public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s = s.toLowerCase( ); c = s.charAt( 0 ); System.out.println( "c = " + c ); System.out.println( "c != 'a' is " + ( c != 'a' ) ); System.out.println( "c != 'b' is " + ( c != 'b' ) ); System.out.println( "( c != 'a' ) && ( c != 'b' ) is " + ( ( c != 'a' ) && ( c != 'b' ) ) ); } while ( ( c != 'a' ) && ( c != 'b' ) ); [mfukuda@perseus css161]$ java DebugExample Enter 'A' for option A or 'B' for option B. A c = a c != 'a' is false c != 'b' is true ( c != 'a' ) && ( c != 'b' ) is false [mfukuda@perseus css161]$ CSS161: Fundamentals of Computing
Debugging Example (10 of 10) Use a Boolean variable with a meaningful name to control the do-while loop. import java.util.Scanner; public class DebugExample { public static void main( String[] args ) { String s = ""; char c = ' '; Scanner keyboard = new Scanner( System.in ); boolean invalidKey; do { System.out.println("Enter 'A' for option A or 'B' for option B."); s = keyboard.next( ); s = s.toLowerCase( ); c = s.charAt( 0 ); if ( c == 'a' ) invalidKey = false; else if ( c == 'b' ) else invalidKey = true; } while ( invalidKey ); CSS161: Fundamentals of Computing
CSS161: Fundamentals of Computing Assertion Checks Syntax assert Expression1 : Expression2; where Expression1 is a Boolean expression. Expression2 is an expression that has a value Usage Place an assertion to check the state of your program, (i.e., conditions, invariants) For more usage: http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html if ( n % 3 == 0 ) { ...; } else if ( n % 3 == 1 ) { } else { assert n % 3 == 2 : n; // we know n % 3 == 2 } CSS161: Fundamentals of Computing
CSS161: Fundamentals of Computing Preventive Coding Incremental Development Write a little bit of code at a time and test it before moving on Code Review Have others look at your code Pair Programming Programming in a team, one typing while the other watches, and periodically switch roles CSS161: Fundamentals of Computing
CSS161: Fundamentals of Computing Self-Test Exercises Work on Textbook p153’s exercises 41 ~ 43. CSS161: Fundamentals of Computing