Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CS 121 – Intro to Java - Lecture 19 Announcements Exam end of next week; extra credit assignment posted on website; Program 6 up tonight / tomorrow Ch 9 OWL problems up Next class: CS 187 (CS minor: 121+187 + 3 others; also, a BA in CS - 11 CS classes + minor or major in something else..) Topics for today: Quick review of File io Exceptions Files Quick review, using Echo and inheritance Your computer’s file system is - barring catastrophe permanent It’s the repository of data (your programs, term papers, diary, emails, popular URLs, and so forth) Actually, we’ll distinguish between text files (blah.txt, Infant.java), for which the basic unit is a character, and binary files, for which the basic unit is the byte. One other distinction: files can be read in sequential style - beginning to end (very inefficient for some applications); or in random access file (jump directly to a disk location - much more efficient). Our focus here: sequential text files Some Observations: For many applications, what we do when we read text is done at the line level (e.g. here’s a line: capitalize it, count it, convert it to numbers, look for a word, etc.) At the same time, the file-reading machinery is unchanging: get the name, make a FileReader, make a Scanner, give me the lines We’ll separate these two aspects of DisplayFile, then use inheritance so that we never have to re-examine the unchanging part! public Echo(String f) throws IOException{ fileName = f; scan = new Scanner(new FileReader(fileName)); } public void readLines(){ while(scan.hasNext()){ processLine(scan.nextLine()); } scan.close(); } Core-Unchanging void processLine(){..} to be overwritten in subclass import java.util.Scanner; import java.io.*; public class Echo{ String fileName; // external file name Scanner scan; // reads from external file public Echo(String f) throws IOException{ } fileName = f; scan = new Scanner(new FileReader(fileName)); public void readLines(){ while(scan.hasNext()){ processLine(scan.nextLine()); } scan.close(); } public void processLine(String line){ System.out.println(line); } } import java.util.Scanner; import java.io.*; public class ReadDriver{ public static void main(String[] args) throws IOException { String fileName; Scanner nameReader = new Scanner(System.in); System.out.println("Enter a file name"); fileName = nameReader.nextLine(); Echo e = new Echo(fileName); e.readLines(); } } Write a program that finds the longest line in a text file That is - find line with greatest length. If a tie, any will do Create class LongLine - how is it organized? What are its attributes? How does LongLine object evolve over time? An aside on state.. What is the state of the computation for this method, as computation evolves? public static int arrayMax(int[] nums){ int big = nums[0]; for(int j = 1; j < nums.length; j++) if (nums[j] > big) big = nums[j]; return big; } State of comp is: value of big, and value of j. These change as comp evolves. Where does corr state reside for LongestLine obj? import java.io.*; public class LongLine extends Echo{ private String longLine = ""; private int longLength = 0; LongLine(String f) throws IOException{ super(f); } } public void processLine(String line){ if (line.length() > longLength){ longLine = line; longLength = line.length();} } public void reportWinner(){ System.out.println("winner: " + longLine); } Shadow system for handling errors: Exceptions This is a system of classes and objects that employ special machinery for detectings errors and shifting responsibilites for handling these problems Java recognized two kinds of exceptional behavior: Unchecked exceptions: errors that occur because of flaws in logical thinking on the part of the programmer (e.g. step off end of array) Checked exceptions: errors that can be expected to occur, and may occur despite your best efforts to avoid them (e.g., trying to read from a file that doesn’t exist) The main class we’ll concern ourselves with: The class Exception It has many derived classes: ArithmeticException (unchecked) ArrayOutOfBoundsException (unchecked) IOException (checked) NumberFormatException (unchecked) Exceptions are objects, either from the Exception class or a derived class of the Exception class Exceptions embody - yup - exceptional behavior One attribute: a String message, (with a getMessage() method) One constructor has a String parameter - the message You must acknowledge checked exceptions public class Except0{ public static void main(String[] args){ int k; int a = 3; int b = 0; k = a/b; } } Java reports: Exception in thread "main" java.lang.ArithmeticException: / by zero at Except0.main(Except0.java:4) Two sides to exceptional behavior - detecting and responding Java has special machinery, the try/catch construction, for dealing with exceptions (handling exceptions) An exception is handled (by you) if your code detects the error and takes some action in response -- as in the next example. public static void main(String[] args){ int k; int a = 3; int b = 0; try{ k = a/b; } catch(ArithmeticException e) { System.out.println(e); } } } Java reports: java.lang.ArithmeticException: / by zero The try/catch harness try{ blah // this is normal execution blah } catch(Exception1 e){ } // one kind of except catch(Exception2 e){ } // another kind catch….. public class Except2{ public static void main(String[] args){ String s = "98.6"; int n; try{ n = Integer.parseInt(s); System.out.println(n*n); } catch(Exception e) { e.printStackTrace(); } } } java.lang.NumberFormatException: For input string: "98.6" at java.lang.NumberFormatException.for Input String(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:456) at java.lang.Integer.parseInt(Integer.java:497) at Except2.main(Except2.java:8) What happens if (for above): Blah blah… try{ n = Integer.parseInt(s); System.out.println(n*n); } catch (NumberFormatException e) { } catch (ArrayOutOfBoundsException e) { } What happens if: Blah blah… try{ n = Integer.parseInt(s); System.out.println(n*n); } catch (ArrayOutOfBoundsException e) { } catch (NumberFormatException e) { } try{ } blah; blah; catch (ArrayOutOfBoundsException e) {… } ----------------------------------------------------- try{ } blah; blah; catch (Exception e) {… } Bullet-Proofing You are supposed to enter an integer, representing your age (the code thenreports your age for next year..) System.out.println("enter your age"); n = scan.nextInt(); System.out.println("next year you will be " + (n + 1)); What could go wrong? • n a non-integer • n could be negative “bullet-proofing” (sometimes called “idiot-proofing”) a surprisingly critical part of computing Some interaction: enter your age 39e Bad input. 39e is not an integer. You must input an integer enter your age 39 next year you will be 40 Aside: Still a contrived example - but not completely so… Illustrates an extremely important aspect of computer programming: “bullet-proofing” / “error trapping” / “idiot proofing” import java.io.*; import java.util.*; public class IntegerInput{ public static void main(String[] args){ int n = -1; String userInput; Scanner scan = new Scanner(System.in); while (n < 0) { System.out.println("enter your age"); try { if (scan.hasNextInt()) // false if non-int next n = scan.nextInt(); else { // non integer submitted userInput = scan.next(); // get actual input throw new Exception("Bad input. "+ userInput + " is not an integer. You must input an integer"); } } // end try catch (Exception e){ System.out.println(e.getMessage()); } } // end while System.out.println("next year you will be " + (n + 1)); } } What does throw do? it “presents” an exception object of the indicated kind at a new location in the program.. What if you enter a negative number? Not handled very well (No message).. enter your age -39 enter your age -4 enter your age One way to handle this: make a new kind of Exception.. public class NegativeException extends Exception{ public NegativeException() {super(); }; public NegativeException(String msg){ super(msg); } } And then: while (n < 0) { System.out.println("enter your age"); try { if (scan.hasNextInt()) n = scan.nextInt(); else { String userInput = scan.next(); throw new Exception("Bad input. "+ userInput + " not an integer. You must input an int"); } if (n < 0) throw new NegativeException(); } catch (NegativeException e) { System.out.println("age must be >= 0"); } catch (Exception e) { System.out.println(e.getMessage()); } } // end while System.out.println("next year you will be " + (n + 1)); Notice: two kinds of exceptions, more specific one first One more example You have a data file of numerical data, integers, one per line It may contain errors (deep space info?) You want to compute the average value of the entries - but you’re happy just to skip over the bad data Here is nums.txt 50 60 3e 10 Here’s the output: Bad Entry: 3e 40.0 // note: average of 50, 60, 10 This code also traps for a bad file, and asks you to resubmit import java.util.Scanner; import java.io.*; public class AverageTester{ … public static void main(String[] args){ boolean finished = false; while(!finished){ try{ String fileName; Scanner nameReader = new Scanner(System.in); System.out.println("Enter a file name"); fileName = nameReader.nextLine(); FileAverage e = new FileAverage(fileName); e.readLines(); System.out.println(e.reportAverage()); finished = true; } catch(IOException e){System.out.println("file problem-retry");} catch(Exception e){e.printStackTrace();} } } } import java.io.*; public class FileAverage extends Echo{ int count = 0; double total = 0.0; public FileAverage(String f) throws IOException{ super(f);} public void processLine(String s){ double val; try{ count++; val = Double.parseDouble(s); total = total + val; } catch(Exception e){ System.out.print("bad input " + s); System.out.println(" line number: " + count); } } public double reportAverage(){return total/count;} }