Simulators - California State University, Los Angeles

Download Report

Transcript Simulators - California State University, Los Angeles

Lecture 8
CS 202
Errors
Three types of errors
• Syntax/Compile time
• Runtime
• Logic
Errors
Syntax/Compiletime Errors
– Incorrect Java, caught by IDE or compiler
int x == 0;
Errors
Runtime errors occur when an operation is
impossible to carry out. Without additional
handling, they cause the application to crash:
• Read from a file that does not exist
• Integer.parseInt(1.2);
public static void main(String[] args){
int quotient = 0;
for(int counter = 10; counter >=0; counter--){
System.out.print("10 / " + counter + " = ");
quotient = 10/counter;
System.out.println (quotient);
}
}
Errors
Logic Errors
• Logical problems in the application
• Cause incorrect results, not crashes
String[] options = {"Yes", "No"};
int buy = 0;
JOptionPane.showOptionDialog(null, "Place Order?", "Buy Dialog",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, "Yes");
if(x ==0);
buyProduct();
Stack Trace
• A stack trace is a list of method calls and code line numbers,
usually seen when an error occurs:
• You should love a stack trace like a mother who only criticizes
you for your own good.
• Note that you can tell what line of your code was executing
when the error occurred, but you may have to read several lines
of the trace to get to it.
Exceptions
Definitions of "exception:"
• Wikipedia:
"An anomalous event requiring special processing"
• Liang Introduction To Java Programming, referring to Java
exceptions specifically:
"An object that represents an error or condition that prevents
execution from proceeding normally."
• In Java, an exception is an object!
• Various kinds of Exceptions are defined in different Exception
classes.
• Exception classes have methods; the ones you are likely to use
involve stack traces and error messages.
• Exceptions are "raised" or "thrown" by code, either written by you
or by the author of a class you are using.
Exceptions:
• You can create your own exceptions to deal with the problems that are likely to
arise in your programs, but for now, use the ones that are built in to the Java
API. You have already encountered many of these
• This code will raise a StackOverflowException :
public class Demo {
int x;
public Demo(int oldX){
x = oldX + 1;
System.out.println(x);
Demo d = new Demo(x);
}
public static void main(String[] args) {
Demo demo = new Demo(1);
}
}
Exceptions
• Try/Catch:
• Run an exception-prone operation in try{}; if
an exception occurs, deal with it in catch{}
• Optional finally{} runs after the try code,
whether or not an exception occurs
Try…catch…finally
Try-Catch-Finally
try{
error-prone code
}
catch(TypeOfException nameForException){
what to do if this type of exception occurs
}
catch(OtherTypeOfException nameForException){
what to do if this type of exception occurs
}
catch(Exception ex){
what to do if any other type of exception occurs
}
…
finally{
code to execute afterwards, whether or not an exception occurred
}
Throwing Exceptions
• The exceptions we have seen so far are thrown by code you did
not write
• You can also check for exceptional conditions and throw
exceptions, either standard ones or your own
• See the textbook for syntax for creating your own exception
types. Only do this when none of the standard ones seem
correct.
Try-Catch-Finally
• Consider this error-prone code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter two numbers:");
double num1 = input.nextDouble();
double num2 = input.nextDouble();
double result = num1 / num2;
System.out.println(num1 + "/" + num2 + "=" + result);
input.close();
}
Try-Catch-Finally
public static double quotient(double num1, double num2) {
if (num2 == 0)
throw new ArithmeticException("Divisor cannot be zero");
return num1 / num2;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter two numbers:");
try {
double num1 = input.nextDouble();
double num2 = input.nextDouble();
double result = quotient(num1, num2);
System.out.println(num1 + "/" + num2 + "=" + result);
}
catch (ArithmeticException ex) {
System.out.println(ex.getMessage());
} finally {
input.close();
}
System.out.println("festivities continue without a crash!");
}
Checked Exceptions
• The compiler will force you to handle certain kinds of exceptions;
these are called Checked Exceptions.
• Recall the file operations in week 2. Since file I/O is so errorprone, many file operations throw exceptions which you must
catch in order to use the File, PrintWriter, etc. classes.
Simulators
• Imagine you need data to test software that will be
used to process real-world measurements, like the
ages of college students
• Sometimes you might want linearly-distributed data,
but Gaussian (normal) distributions are often more
realistic
• Random.nextGaussian() returns a double from a
normal distribution with standard deviation = 1 and
mean = 0. Multiply it by the desired STD and then add
the desired mean
package simulator;
import java.util.Arrays;
public class Grader {
private double average;
private double std;
private int classSize;
private double[] grades;
private final double MINGRADE = 0;
private final double MAXGRADE = 100;
public enum GradingType {
LINEAR, GAUSSIAN
};
public Grader(double avgIn, double stdIn, int classSizeIn) {
average = avgIn;
std = stdIn;
classSize = classSizeIn;
}
public static void main(String[] args) {
Grader grd = new Grader(80d, 10d, 20);
grd.grade(GradingType.LINEAR);
grd.grade(GradingType.GAUSSIAN);
}
private void grade(GradingType type) {
Simulator sim = new Simulator();
if (type == GradingType.LINEAR)
grades = sim.getLinearData(classSize, MINGRADE, MAXGRADE);
if (type == GradingType.GAUSSIAN)
grades = sim.getGaussianData(average, std, classSize, MINGRADE,
MAXGRADE);
System.out.println("\nData using distribution type: " + type + "\n");
for (int i = 0; i < grades.length; i++) {
System.out.print("Student #" + i + " received a grade of ");
System.out.printf("%3.1f\n", grades[i]);
}
Arrays.sort(grades);
System.out.println("Here are the sorted values from the simulator:");
for (double d : grades)
System.out.printf("%3.1f\n",d);
}
}
package simulator;
import java.util.Random;
public class Simulator {
private static double[] nums;
public double[] getGaussianData(double mean, double std, int count, double min, double max) {
Random r = new Random();
nums = new double[count];
double randDoub;
for (int counter = 0; counter < nums.length; counter++){
randDoub = r.nextGaussian() * std + mean;
// it's pretty hard to set limits for the values in a good way, so here is a hacky way.
if(randDoub > max) randDoub = max;
if(randDoub < min) randDoub = min;
nums[counter] = randDoub;
}
return nums;
}
public double[] getLinearData(int count, double min, double max) {
// it would be better to make sure max < min first, but I am not implementing this in this example
Random r = new Random();
nums = new double[count];
double randDoub;
for (int counter = 0; counter < nums.length; counter++){
randDoub = r.nextDouble() * (max - min) + min;
nums[counter] = randDoub;
}
return nums;
}
}
Separate Things That Are Likely To Change Independently
• Grader is domain-specific (only useful for a narrow type of
problem, in this case grading schoolwork)
• Simulator, on the other hand, does not contain anything that
shows it is from an application that simulates grading. It could
be used to generate test data for a very wide variety of problems
• This is an example of an important principle in software
engineering. Separate the general from the specific, and
separate things you can probably reuse from things you can't. If
two things are likely to change independently of each other,
don’t combine them.
– "When all you have is a hammer, everything looks like a nail" – folk proverb
– "If I had a hammer, I'd hammer in the morning, I'd hammer in the evening, all over this land.
I'd hammer out danger; I'd hammer out a warning; I'd hammer out love between my
brothers and my sisters, all over this land." –Pete Seeger
Instanceof
• The next demo uses Java's instanceof operator, which
determines whether an object is an instance of a
particular class
• The syntax of instanceof may be counterintuitive; the
keyword does not use camel case and there are no
parentheses around the class name
• The next slide shows a simple demo of instanceof
Instanceof
package demos;
public class Demo {
Object myObject;
public void setMyObject(Object o) {
myObject = o;
}
public Object getMyObject() {
return myObject;
}
public static void main(String[] args) {
Demo demo = new Demo();
String newObject = new String("John");
demo.setMyObject(newObject);
Object o = demo.getMyObject();
if (o instanceof String)
System.out.println("\"" + o + "\"" + " is a String!");
else
System.out.println("not a String!");
Object arch = new Archimedes();
demo.setMyObject(arch);
Object o2 = demo.getMyObject();
if (o2 instanceof String)
System.out.println("\"" + 02 + "\"" + " is a String!");
else
System.out.println(o2 + " is not a String!");
}
}