IT 114: Introduction to Java
Class 19
Topics
Review
New Material
Homework 7
Homework 7 is not due this Sunday.
Instead it is due the Sunday after the Mid-term Exam.
This will give you time to study for the exam.
You will find the assignment here.
If you have a problem or a question, make a post on the Class Discussion Area.
Mid-term
The mid-term exam will be given on Monday, March 23rd.
It will consist of questions like those on the quizzes along with questions
asking you to write short segments of Java code.
60% of the points on this exam will consist of questions from the Ungraded Class Quizzes.
The other 40% will come from four questions that ask you to write a short segment of code.
The last class before the exam, Friday, March 13th, will be a review session.
You will only be responsible for the material in the Class Notes for that class on the exam.
The Mid-term is a closed book exam.
Due Date for Homework Assignments 2 - 6
The due date for homework assignments 2 - 6
is Friday, March 20th at 11:59 PM.
It is also the due date for Class Exercises 2 - 17
That is the Friday of the Spring Break.
Any of these assignments submitted after that date
will receive a score of 0.
Review
Errors
- It is easy to get an error when writing programs
- But to fix errors it is important to recognize the different types
- There are three classes of errors
- Syntax errors
- Logic errors
- Runtime errors
Syntax Errors
Logic Errors
- A logic error
occurs when the code does not give the correct results
- When you have a syntax error the Python interpreter will tell you
- The error message it gives specifies the kind of error and prints the line
- But you get no warning with a logic error
- The code works and unless you check the results you will not know there is a problem
- This is why it is always important run tests on the scripts you write
- Even if you know there is an error it can be hard to find
- The problem could be anywhere in the code
- It is hard to spot your own errors
- That is why smart people ask others to proof read what they write
Runtime Errors
- Runtime errors
occur only when the the program is run
- They occur when a value in the program makes a statement fail
- If the program is run again with a different value no runtime error would occur
Exceptions Objects
- Many computer languages have a mechanism built into the language that deals with runtime errors
- It gathers information about what happened and where
- And uses that information to create an error message
- The error message describes the problem and where it occurred
- It does this by creating an
exception object
- When this happens we say that the interpreter has
raised an exception
Catching Exceptions
Data Validation
- There is a saying in data processing circles
Garbage in
Garbage out
- This is sometimes abbreviated as GIGO
- It means the output of a program is only as good as the quality of
data input
- Whenever you ask a user for input you should check it
- There are two things that should be checked
- If the data is of the correct type (integer, decimal, string)
- If the value of the data is correct
- The second test particularly important for numbers
- There is usually a range of values that make sense for a program
- Temperatures in Celsius cannot be lower than 273 degrees
- That is absolute zero in Celsius
- There is no upper limit for temperature
- But most programs probably should not accept values above
the boiling point of water
- Which is 100 degrees Celsius
Data Validation Loops
Flags
- The variable done in the code above is an example of a
- A flag is a boolean variable that indicates some condition or state
- For example ticket application might ask a patient's age
- And then use that value to set flags for minor
and senior
- These flags would then be used in
if
statements
or while
loops later in the code
New Material
Data Validation for Type
Methods Checking Value and Type of Input
- If we run AboveZero3.java and enter
a value that can't be converted to an Integer we get
$ java AboveZero3
Integer greater than zero: Integer greater than zero: foo
Exception in thread "main" java.util.InputMismatchException
...
- Let's create a new version of the program keeps running
until it gets a value that can be converted
- We need to change the method get_value_above_zero
- AboveZero3.py gets an integer from the user
with this statement
number = con.nextInt();
- But that statement will fail if we the user enters something that
can't be turned into a integer
- So we need to replace it with a call to a new method
number = get_integer(con);
- This new method has one purpose
- It will keep looping until the user enters a string
that can be converted into an integer
- When it gets that string to an integer
- And return it to the calling method
- Here is the code for get_integer
public static int get_integer(Scanner con){
int number = 0;
String input = "";
while (true){
try {
System.out.print("Integer greater than zero: ");
input = con.next();
return Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("Cannot convert " + input + " into an integer");
}
}
}
- Running this new program we get
$ java AboveZero4 five
Integer greater than zero: Integer greater than zero: five
Cannot convert five into an integer
Integer greater than zero: -9
The integer must be greater than 0
Integer greater than zero: 0
The integer must be greater than 0
Integer greater than zero: 45
45
- You can see the code for AboveZero4.java
here
Files
- Programs need data to do their work
- Manual data entry is slow and often inaccurate
- What if we needed a large amount of data to perform some task?
- When a large company does its payroll it needs data on every employee
- When processing large amount of data we need to use
files
- A file is simply a linear arrangement of data on some long term storage device
- That storage medium might be a
- Hard disk
- Flash drive
- CD ROM
- SSD card
Types of Files
- All files consist of binary numbers
- But those numbers can be interpreted in two ways
- Consider the following text file
$ cat fruit.txt
grapes
pears
oranges
cranberries
apples
melons
blueberries
- The Unix
od
(octal dump) command shows how
this file is stored on disk
$ od -b fruit.txt
0000000 147 162 141 160 145 163 012 160 145 141 162 163 012 157 162 141
0000020 156 147 145 163 012 143 162 141 156 142 145 162 162 151 145 163
0000040 012 141 160 160 154 145 163 012 155 145 154 157 156 163 012 142
0000060 154 165 145 142 145 162 162 151 145 163 012
0000073
- The first column is the offset
- It is how far the data on the right is from the start of the file
- Every column after the first shows the
octal value of a
byte in the file
- Each byte of the file represents a character in Unicode
- To see the characters, I can run
od
with the -c
option
od -c fruit.txt
0000000 g r a p e s \n p e a r s \n o r a
0000020 n g e s \n c r a n b e r r i e s
0000040 \n a p p l e s \n m e l o n s \n b
0000060 l u e b e r r i e s \n
0000073
- A binary file, such as a JPEG image also consist of numbers
- Consider the JPEG file that holds the following image
- When we look at this with
od
we get
$ od -b square.jpg
0000000 377 330 377 340 000 020 112 106 111 106 000 001 001 000 000 110
0000020 000 110 000 000 377 341 000 200 105 170 151 146 000 000 115 115
0000040 000 052 000 000 000 010 000 004 001 032 000 005 000 000 000 001
...
- Trying to interpret it as text gives us garbage
$ od -c square.jpg | head
0000000 377 330 377 340 \0 020 J F I F \0 001 001 \0 \0 H
0000020 \0 H \0 \0 377 341 \0 200 E x i f \0 \0 M M
0000040 \0 * \0 \0 \0 \b \0 004 001 032 \0 005 \0 \0 \0 001
...
- Both files contain binary numbers
- But the numbers in the text file represent Unicode characters
- They make sense when we use them as text
- The JPEG numbers make no sense if we try to use them as text
- Text files have a simple structure
- Each file is a collection of lines
- A line is a series of characters followed by the newline character \n
- We will only be using text files in this course
Identifying a File
- We need two pieces of information to identify a file
- Operating systems have different rules about the characters in a filename
- Linux and Unix are
case sensitive
- This means that memo.txt and MEMO.txt
are different file names
- Windows is not case sensitive
- You cannot have two files with the same name inside any one directory
- The location of a file is given by a
path
- A path is a list of directories
- The path tells what directory holds the file
Storing Data on a Hard Disk
- Every type of storage device has it's own way of storing data
- Hard disks consists of rapidly spinning disks
- The disks contain information in the form of magnetic fields
- The disk is made up of material that can be magnetized
- This material consists of billions of small regions
- In each regions the magnetic field points in some direction
- Each of these fields represents a binary digit called a
bit
- The direction can be either up or down
- One direction means 0 and the other means 1
- The surface of the disk is broken up into rings called tracks
- And each track is broken up into sectors
- Most files consist of many sectors
- And the sectors do not have to be one right after the other
- The sectors of a file can be scattered all over the hard disk
Files and the Kernel
- A file can be scattered over different sectors of the disk
- So how does the operating system know where to get the different parts?
- It doesn't have to
- That's the job of the
device driver
- The device driver is software that allows the device to talk to the computer
- Device drivers must be provided by the manufacturer
- If you install a new printer on your machine
you the right device driver to talk to it
- At the core of every operating system is a program called the
kernel
- The kernel handles all interactions with hardware
- When a program needs a file it must ask the kernel to get a connection to the file
- The kernel in turn gets that data from the device driver
- The kernel does not have to worry about where the file is stored on the disk
- That's the job of the device driver
- Give the kernel the name and location of a file
- And it will find the device driver to get it
- This division of labor makes everything work better
- It means that you can work with files on many different devices
Getting Data From a File in Java
- You can think of a program as code that deals with streams of data
- It takes data from an input stream
- And produces an output stream
- The input stream can come from the keyboard
- Or from a file
- The output stream can go to the screen
- Or to a file
- Previously we used Scanner object that we used to get
input to get input from the key
- A Scanner object can also be used with a file
- After all a file is just another data stream
Using a Scanner Object with a File
- To use a Scanner object to get input from the
keyboard you write
Scanner console = new Scanner(System.in);
- The argument System.in is variable pointing to an
object that represents the keyboard
- To create a Scanner object for a file
we a different argument
- We need to create a File object
- But first we have to import the File
class
- We could do this as follows
import java.io.File;
- But it turns out we will be needing other classes from this package
- So we will import all of them
import java.io.*
- To create a file object from a
pathname
given at the command line we would write
File file = new File(args[0]);
- Now we can use file to create a
Scanner object
- Here is a small program to do this
simport java.io.*;
import java.util.Scanner;
public class OpenFile {
public static void main (String[] args){
File file = new File(args[0]);
Scanner input = new Scanner(file);
}
}
- But when we try to compile this we get the following
$ javac OpenFile.java
OpenFile.java:7: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
Scanner input = new Scanner(file);
^
1 error
- Note that the runtime did not occur when we created the file object
- It occurred when we tried to use this file object as an argument
when creating the Scanner object
- This means that we can create a file object for a file that does not exist
- This is one of many peculiarities of Java
Two Kinds of Java Exceptions
- Java recognizes two types of Exceptions
- Checked Exceptions
- Unchecked Exceptions
- A checked exception
is one that is so serious it must be handled with
- There are two ways you can handle checked exceptions
- You can put the statement that might cause the exception
inside the
try
block of a try
/catch
statement
- Or you can add a
throws clause
to the method header
- A throws clause has the following format
throws EXCEPTION_NAME
- We can add a throws clause to the header of the main
method like this
import java.io.*;
import java.util.Scanner;
public class OpenFile2 {
public static void main (String[] args)
throws FileNotFoundException {
File file = new File(args[0]);
Scanner input = new Scanner(file);
}
}
- This new version will compile
- And it gives us no trouble when we run it with an existing file
$ java OpenFile2 numbers.txt
$
- But we will crash down to the command line if we try to
open a file that does not exist
$ java OpenFile2 foo.txt
Exception in thread "main" java.io.FileNotFoundException: foo.txt (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.util.Scanner.<init>(Scanner.java:611)
at OpenFile2.main(OpenFile2.java:8)
Creating Scanner without a Throws Clause
- Dealing with the checked exception with a
throws
clause works
- But it is not very elegant
- It would be much better to create a Scanner
inside a
try
/except
statement
- This way we can catch the exception and print an error message
- And not crash down to the command line
- This is known in programming circles as "Failing gracefully"
- Here is code that will do this inside the main
method
import java.io.*;
import java.util.Scanner;
public class ScannerCreate {
public static void main (String[] args){
String pathname = args[0];
try {
File file = new File(pathname);
Scanner input = new Scanner(file);
} catch (FileNotFoundException e){
System.out.println("Cannot open " + pathname);
}
}
}
- Here is what we get when we run it
$ java ScannerCreate numbers.txt
$ java ScannerCreate xxx.txt
Cannot open xxx.txt
- Notice that we do not crash down to the command line
if we try to create a Scanner object
on a file that does not exist
Creating a Scanner with a Method
- What about creating a method to handle the job of creating a
Scanner object?
- If we do this we would have to have the
return type be
of type Scanner
public static Scanner create_scanner(String pathname){
- And we could use the following
try
/catch
statement
try {
File file = new File(pathname);
Scanner input = new Scanner(file);
return input;
} catch (FileNotFoundException e){
System.out.println("Cannot open " + pathname);
System.exit(0);
}
- But that code would not compile
$ javac ScannerCreate2.java
ScannerCreate2.java:17: error: missing return statement
}
^
1 error
because we did not return a Scanner object
- As promised by the return type
- We would need to replace
System.exit(0);
with a statement that returned a Scanner object
- We could use something like
return new Scanner(System.in);
- But that would be a
kludge
- A kludge is an inelegant solution to a problem
- Like fixing a broken car window with plastic wrap and duct tape
Class Quiz
Attendance
Class Exercise