What We Will Cover
Continuations
Homework Questions?
Feedback on CodeLab
^ top
9.1: More Control Statements
Objectives
At the end of the lesson the student will be able to:
- Use
switch statements for branching
- Use
do-while statements to control loops
- Use
for statements to control loops
- Use
break and continue statements with loops
|
- In this section, we learn about the rest of Java's control statements
- These statements do not add new capabilities
- Just provide alternate ways of performing some tasks
- Since Java code has them, you need to know how to use them
^ top
9.1.1: switch Statements
The switch statement provides an alternative to an if-else chain
Executes a section of code depending on value of a variable
General form:
switch (integerExpression) {
case label1:
statements
break;
case label2:
statements
break;
...
case labeln:
statements
break;
default:
statements
break;
}
Keyword switch identifies the start of the switch statement
Expression in parenthesis is evaluated for comparison to each case label
integerExpression must evaluate to an integer
- Otherwise a compilation error occurs
Within a switch statement, keyword case labels each entry point into the code
- Code executes if
integerExpression matches the case label value
- Execution starts with the statement immediately following the match
Any number of case labels can be placed in any order
Any value that does not match starts executing with the statement after default
Execution continues until the end of the switch statement or a break statement
The break statement causes an immediate exit from the switch statement
Just as case identifies possible starting points, break determines end points
For Example:
import java.util.Scanner;
public class GradeSwitchApp {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("I show a grade based on a"
+ " score.\nEnter your score: ");
int score = input.nextInt();
switch (score / 10) {
case 10:
case 9:
System.out.println("You got an A");
break;
case 8:
System.out.println("You got a B");
break;
case 7:
System.out.println("You got a C");
break;
case 6:
System.out.println("You got a D");
break;
default:
System.out.println("Sorry, an F");
}
}
}
- Notice that each
case other than the last contains a break statement
- Ensures that the
switch statement is exited after a matching case is found
When to Use switch Statements
- You can only use switch statements with integer expressions
- Inherently less useful than
if-else statements
- Syntax is no clearer than
if-else statements
- Thus, no real need to ever use a switch statement
- One acceptable use is for a menu
^ top
9.1.2: Conditional (Ternary) Operators
- Provides a compact
if-else structure
- Syntax:
operand1 ? operand2 : operand3;
First operand must be a conditional expression that evaluates to true or false
If operand1 is true, return operand2; otherwise return operand3.
For Example
- Following is an if-else statement
String outMessage;
double celsius = 50;
if (celsius >= 100) {
outMessage = "Boiling!";
} else {
outMessage = "Not boiling";
}
System.out.println(outMessage);
Equivalent using the conditional operator
String outMessage;
double celsius = 50;
outMessage = (celsius > 100)
? "Boiling!"
: "Not boiling";
System.out.println(outMessage);
When to Use Conditional (Ternary) Operators
- Rarely used in professional programing
- Almost always better to use
if-else statements
^ top
9.1.3: do-while Statements
- Variation of the
while loop
- Syntax:
//Initialization
...
do {
//loop body
...
} while (loopTest); //loop condition
Initialization code may precede loop body
Loop test is after the loop body
Loop must execute at least once (minimum of at least one iteration)
Use when you want to force a minimum of one iteration
Validity Checks
- Can use
do-while statements to filter user input
- For example, assume we need a positive value from the user:
import java.util.Scanner;
import static java.lang.System.out;
public class SumInputDo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//Loop initialization
double num = 0.0;
do {
//loop body
out.print("Enter a positive number: ");
num = input.nextDouble();
if (num < 0.0) {
out.println("The number must be >= 0");
}
} while (num < 0.0); //loop condition
System.out.println("You entered: " + num);
}
}
When to Use do-while Statements
- Sometimes used in professional programming
- Can accomplish the same control flow with a
while loop
- Use it when you want to force a minimum of one iteration
^ top
9.1.4: for Statements
- Provides a more compact loop
- Syntax:
for (initializer; condition; increment) {
//loop body
...
}
Initialization, loop-test, and increment-expression are part of the syntax
initializer expression: defines the initial value used to control the loop
condition expression: determines when the loop will end
increment expression: evaluated at the end of each loop iteration
Statements to repeat are enclosed in curly brackets
Execution sequence as follows:
- When
for statement reached -- initialization executes
- Check if condition is
true
- if
true then continue with Step 3
- Otherwise, continue with Step 6
- Execute block containing the loop body
- When end of loop body is reached, execute the increment
- Return to Step 2
- Loop is finished: continue with statements after the loop
Counter-Controlled-Loop Example
public class CounterFor {
public static void main(String[] args) {
int count;
for (count = 0; count < 5; count++) {
System.out.println(count);
}
}
}
Note that code is indented in the loop body for readability
Counting Down
- Can also count downwards
- Positive numbers step higher (+inf) and negative numbers step lower (-inf)
- What is displayed with the following?
public class CountDown {
public static void main(String[] args) {
int count;
for (count = 5; count > 0 ; count--) {
System.out.println(count);
}
}
}
When to Use for Statements
- Very often used in professional programming
- Especially useful for counter-controlled loops
^ top
9.1.5: break and continue Statements
break and continue statements transfer control to another part of a program
- Within a loop
break statements an immediate exit
- Transfers control to statement following the loop
- Provides a way to break out of an intentional infinite loop
public class BreakOut {
public static void main(String[] args) {
int count = 0;
while (true) {
count++;
if (count == 3) continue;
System.out.println(count);
if (count >= 5) break;
}
System.out.println("After count= " + count);
}
}
continue statement transfers control to the loop condition
Causes the loop to skip the rest of the current iteration
When encountered in a loop, starts the next iteration of the loop immediately
When to Use break and continue Statements
- Use
break statements in switch statements only
- Never use
break in looping constructs
- Poor coding habit
- Should only have one exit point in a loop
- In this course, you will never a need to write infinite loops like that shown above
- Do not need to use
continue statements either
- Can accomplish the same operation other ways
^ top
9.1.6: Summary
- Java provides many control statements
- They provide alternatives to the basic statements covered earlier
- Of those covered today, the most useful is the
for loop
- Provides a compact looping structure often used for counter-controlled repetition
- Includes three of the loop requirements in the syntax of the loop
Check Yourself
- What is the difference between a
while and a do-while loop?
- What are the advantages of using a
for loop compared to other looping statements?
^ top
Exercise 9.1
In this exercise we explore the interchangeability of loops.
Specifications
- Start a text file named exercise9.txt.
- Prepare the exercise header as described in the HowTo on submitting in-class exercises
- Label this exercise: Exercise 9.1
- Save the following code as
Counter5.java.
- Convert the code to use a
for loop rather than a while loop.
- Turn in the modified code along with your exercise9.txt file
- Record answers to the following questions in exercise9.txt.
Q1: What is the chief advantage of using a for loop?
Q2: The for loop seems most appropriate for which type of loop?
public class Counter5 {
public static void main(String[] args) {
int count = 1; // initialize counter
while (count < 6) { //loop condition
//loop body
System.out.println(count);
count++; // adjust the counter
}
System.out.println("After loop count = " + count);
}
}
^ top
9.2: Strings and Characters
Objectives
At the end of the lesson the student will be able to:
- Create strings in Java programs
- Compare string equality
- Use
charAt() to extract characters from a string
|
^ top
9.2.1: About Strings and Characters
- Recall that a string is a sequence of individual characters
- The following diagram shows how the string
Hello is stored

- Note that the first character of a string is position 0, not 1
String Variables are Reference Types
String data types are actually objects in Java
- A
String variable does not store the characters of the string
- Instead, a
String variable stores the location of a String object in memory
- For instance:
String message;
message = new String("Hello");
The first line declares a reference variable of type String
The second line creates a String object in memory and assigns the object location to the reference variable
The keyword new creates the storage for an object and returns its memory location

You can combine the two steps into one line:
String message = new String("Hello");
When you use a String variable, like in the statement above, the value of the variable is not displayed
Instead, Java finds the location of the object and uses the object itself
- This is known as dereferencing the variable
- Unlike some languages, Java automatically dereferences variables when needed
Thus, when we write a statement like:
System.out.println(message);
The content of the object referred to by the String variable gets displayed
It is common to refer to a reference variable as if it contains a value
- This is a convenient mental shorthand
However, it is important to understand that this is technically incorrect
A reference variable always contains the memory address of where an object is stored
We will see a consequence of reference variables shortly
^ top
9.2.2: Creating Strings
- As we saw, you can create a
String using the new keyword
String message = new String("Hello");
String literals have a special syntax that does not require the new keyword
String message = "Hello";
Since this form is shorter, it is more often used
Even with the shorter form, a String is class type and it has constructors and methods
Some of the commonly used constructors are shown below
In addition, we show alternate ways to create strings and append to strings in the following examples
Commonly Used Constructors of Class String
| Constructor |
Description |
String() |
Creates an empty String object. |
String(String original) |
Creates an new String object with the same sequence of characters as the original String object. |
Two Ways to Create an Empty String
String message = "";
String message = new String();
Two Ways to Create a new String From Another String
String message = "Hello";
String message2 = new String(message);
Appending One String to Another
String message = "Hello";
String message2 += " Mom!"
^ top
9.2.3: String Class Methods
- Because strings are class types, most operations on strings use
String class methods
- One exception is assignment, which uses the equals operator
- Another exception is concatenation, which uses the
+ sign
- Some commonly-used methods are shown below
Some Commonly-Used Methods of Class String
| Method |
Description |
| length() |
Returns the number of characters in the string as an int. |
| charAt(int index) |
Returns a char at the specified index. |
| equals(String other) |
Compares two strings for equality and returns true if they are equal and false otherwise. |
| equalsIgnoreCase(String other) |
Compares two strings for equality, ignoring upper or lower case, and returns true if they are equal and false otherwise. |
| toLowerCase() |
Returns a new string with all characters in lowercase. |
| toUpperCase() |
Returns a new string with all characters in uppercase. |
| substring(int start, int end) |
Returns a new string with all the characters from start up to, but not including, end. |
| trim() |
Returns a new string with all whitespace removed from the beginning and end. |
Some Example Uses of String Methods
1
2
3
4
5
6
7
8
9
10
|
public class StringMethods {
public static void main(String[] args) {
String example = "Hello Mom!";
System.out.println(example);
System.out.println(example.length());
System.out.println(example.charAt(0));
System.out.println(example.toLowerCase());
System.out.println(example.toUpperCase());
}
}
|
^ top
9.2.4: Comparing String Equality
- "
==" does not act like you may think for String objects
- "
==" tests to see if the address of the two objects are the same
- The reason is that the two strings,
s1 and s2, refer to different objects

- You must use the
equals() method to test if the String contents are equal
- Use
equals() when case matters
- Use
equalsIgnoreCase() when case does NOT matter
- The following example shows the result of using
== and the methods equals() and equalsIgnoreCase()
Example of Comparing Strings
import java.util.*;
public class StringComparer {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter string 1: ");
String s1 = input.next();
System.out.print("Enter string 2: ");
String s2 = input.next();
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));
}
}
^ top
9.2.5: Iterating Strings
- Since method
charAt() extracts an individual char from a String, we can look at each string character individually
- One convenient way is to use a loop to look at each character
- For instance, what if we needed to filter a telephone number
- A user enters a telephone number but may enter extraneous characters
- For example: 831/477-3576
- For our algorithm, we extract each
char in order using a counting loop
- Once we have the character, we test it to see if it is a digit
- If the character is a digit, then we append it to another string
- Otherwise, we discard the character
- In pseudocode we have:
For each character in the string phoneNumber
character = phoneNumber.charAt(i);
if (character >= '0' && character <= '9')
filteredNumber += character;
We need to know when to exit our loop
Since we are counting characters, we can use String method length()
- Recall that
length() returns the number of characters in a String
With the length() method we can set up a counting loop like:
for (int i = 0; i < phoneNumber.length(); i++) {
// body of the loop
}
The following example implements our algorithm
Example of filtering a Phone Number
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import java.util.*;
public class PhoneFilter {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String filteredNumber = "";
System.out.print("Enter a phone number: ");
String phoneNumber = input.nextLine();
for (int i = 0; i < phoneNumber.length(); i++) {
char ch = phoneNumber.charAt(i);
if (ch >= '0' && ch <= '9') {
filteredNumber += ch;
}
}
System.out.println("Your filtered number: "
+ filteredNumber);
}
}
|
^ top
9.2.6: Summary
- Strings are a sequence of individual characters

- Since strings are objects, they have both constructors and methods
String message = new String("Hello");
Strings have a special shortened object-creation syntax that is normally used
String message = "Hello";
When you compare strings, you need to use the equals() method rather than ==
string1.equals(string2)
You can use methods of the String class to iterate through a string
String phoneNumber = input.nextLine();
for (int i = 0; i < phoneNumber.length(); i++) {
char ch = phoneNumber.charAt(i);
if (ch >= '0' && ch <= '9') {
filteredNumber += ch;
}
}
We used the above to filter phone numbers
^ top
Exercise 9.2
Strings are made up of characters. To explore how strings and characters are related, complete the program following the specifications.
Specifications
- Use the starter code shown below to get started on this exercise.
- Save the code as:
VerticalMessage.java
- Write a program that asks the user for a message and then prints the message vertically down the page.
- Use a loop and the
charAt() method to extract each character from message.
- Submit your source code file as the answer to this exercise.
Sample Output
Enter a message: Hello
H
e
l
l
o
Starter Code
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.util.*;
public class VerticalMessage {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a message: ");
String message = input.nextLine();
// Enter code here
}
}
|
^ top
9.3: Exception Handling Basics
Objectives
At the end of the lesson the student will be able to:
- Describe the Java syntax for exception handling
- Write code to catch and handle exceptions
- Generate code to handle user-input errors
|
^ top
9.3.1: About Exceptions
- A common way to develop a program is to first make the code work assuming that nothing unusual happens
- After the usual case works, then you start to consider the exceptional cases like:
- Users enter letters when you want numbers
- A file your program needs was moved or deleted
- Java helps you to write your code in just this way
- You first write your code as if nothing unusual will happen
- When the usual case works correctly, you add code to handle exceptional cases
- The mechanism to handle the unusual cases is known as exception handling
- Exception handling is an important part of developing "solid" or "robust" programs
- A solid or robust program means that you can run the program day after day
- If crazy or unusual things happen, the program copes or at least recognizes that something is wrong
Terminology
- Exception: an error condition that changes the normal flow of a program
- Throw an exception: either the Java runtime or your code signals that something unusual happened
- Catch an exception: take appropriate action to deal with an exception
- Exception handler: the code that processes an exception
^ top
9.3.2: Exception Example
- Many exceptions can occur because of user input errors
- As an example, let us look at how you might handle user input errors
The Usual Case
- Following is a simple program showing the usual case
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import java.util.*;
public class ReceiptCalculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
System.out.print("Enter net cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
System.out.println("All done!");
}
}
|
- The program works for the usual case but can fail on invalid data
- What happens if the user enters letters instead of numbers?
- What if the user enters
Ctrl-C
Enter net cost: $100
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextDouble(Scanner.java:2335)
at ReceiptCalculator.main(ReceiptCalculator.java:9)
- The program prints the message shown above and then ends
- This is not desirable behavior, so we need to catch and handle the exception
- In Java, you catch and handle exceptions with a try-catch block
^ top
9.3.3: Using try-catch
- To catch and handle exceptions you use both
try and catch statements
- The code that can cause an exception goes inside a
try block
- Code to handle the exception goes inside a
catch block
- Syntax:
try {
// One or more statements that can throw an exception
} catch(Exception e) {
// Exception handling code
// Can have many catch blocks
}
For Example
- Here is an example with try and catch blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
public class ReceiptCalculator2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
try {
System.out.print("Enter net cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
System.out.println("All done!");
}
}
|
- The program works the same way in the normal case
- When the uses enters bad data, our program can do something about it now
Enter net cost: $100
Error -- enter digits only!
Thanks for using us!
Exiting when there is a user input error is usually not the best thing to do
Ideally, we want our program to:
- Describe the problem to the user
- Let the user correct the entry
However, our program does not allow the user to correct the problem yet
To allow the user to correct the problem, we must first understand an exception's flow of control
^ top
9.3.4: Exception Flow of Control
- When an exception occurs while a method is executing:
- Method stops processing at the point of failure
- The code creates an object with the error information
- JVM tries to locate the exception handling code
- If the exception-handling code is found, the
catch block gets the exception object
- If code cannot be found, the general exception handler is used
- General exception handler displays an error messages on the console like the following and then ends the program
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextDouble(Scanner.java:2335)
at ReceiptCalculator.main(ReceiptCalculator.java:9)
- Let us trace through the flow for our example code
- The user enters bad data and the
main() method stops processing
First number: one
- The scanner object code creates an exception object of type
InputMismatchException
- The program passes the exception object to the
catch statement
catch(InputMismatchException e)
- The exception handling code executes
- The program continues with the code after the catch block
- Note that the program does not execute the second input statement
- As soon as the error occurs, the program jumps to the exception handler
- Program execution continues after the exception handler code
What Type of Exception Can Occur?
- The are two usual ways to determine what exceptions can occur in a program
- The first way is to try the code and see what happens
Enter net cost: $100
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextDouble(Scanner.java:2335)
at ReceiptCalculator.main(ReceiptCalculator.java:9)
- However, you might miss something
- Another way is to look up the possible exceptions in the Java API
- For example, we can look up the documentation for the
Scanner method: nextDouble()
- We examine the list of possible exceptions and determine if and how they can occur
- After we determine how the exceptions can occur, we write code to handle them
^ top
9.3.5: Trying Again
- To allow the user to try again when there is an error, we need to code a loop
- One way is to use a looping statement like the following
Example of Verification Using a Loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.util.*;
public class ReceiptCalculator3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
boolean valid = false;
while (!valid) {
try {
System.out.print("Enter net cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
valid = true;
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.next(); // clear the bad entry
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
}
System.out.println("All done!");
}
}
|
- Running the program we see:
Enter net cost: 100
Enter tax: $6
Error -- enter digits only!
Enter net cost: 100
Enter tax: 6
Total: 106.0
All done!
The program now allows the user to correct their errors and continue
However, the code requires the user to reenter all the numbers
A better solution is to reenter only the number in error
To do this we need to loop on each statement that could cause an exception
This leads to duplicate code
When you have duplicate code with minor differences, what should you use?
We should use a method to handle the data input process
^ top
9.3.6: Verifying in Methods
- Using a method we can group our input and verification code and reduce duplication
- Running the program we see:
Enter net cost: ten
Error -- enter digits only!
Enter net cost: 10
Enter tax: $1.23
Error -- enter digits only!
Enter tax: 1.23
Total: 11.23
All done!
Users can correct individual errors without having to redo all their entries
Also note how much simpler the code in main() appears
Example of Verification Using a Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
import java.util.*;
public class ReceiptCalculator4 {
private static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
double cost = 0, tax = 0;
cost = readDouble("Enter net cost: ");
tax = readDouble("Enter tax: ");
double total = cost + tax;
System.out.println("Total: " + total);
System.out.println("All done!");
}
/**
* Read a double from the console.
*
* @param prompt User prompt to show before input
* @return A double entered by the user.
*/
public static double readDouble(String prompt) {
double number = 0;
boolean valid = false;
while (!valid) {
try {
System.out.print(prompt);
number = input.nextDouble();
valid = true;
} catch (InputMismatchException e) {
System.out.println(
"Error: enter a double number!");
input.next(); // clear the bad entry
} catch (NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
}
return number;
}
}
|
- Programmers commonly develop a library of static input methods like these
^ top
9.3.6: Summary
- A common way to develop a program is to first make the code work assuming that nothing unusual happens
- After the usual case works, then you consider the exceptional cases
- Java provides exception handling to handle these exceptional cases
- To catch and handle exceptions you use both
try and catch statements
try {
// One or more statements that can throw an exception
} catch(Exception e) {
// Exception handling code
// Can have many catch blocks
}
Many exceptions can occur because of user input errors
To allow users to correct their errors, you need to add a looping mechanism around the input statement
boolean valid = false;
while (!valid) {
try {
System.out.print("Enter net cost: ");
cost = input.nextDouble();
// May have more statements
valid = true; // no exceptions so the input is good
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.nextLine(); // clear the '\n'
} // may need more catch statements
}
Since input is a frequent occurrence, it is common to write user input methods
One example is readDouble():
/**
* Read a double from the console.
*
* @param prompt User prompt to show before input
* @return A double entered by the user.
*/
public static double readDouble(String prompt) {
double number = 0;
boolean valid = false;
while (!valid) {
try {
System.out.print(prompt);
number = input.nextDouble();
valid = true;
} catch (InputMismatchException e) {
System.out.println(
"Error: enter a double number!");
} catch (NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
input.nextLine(); // clear the '\n'
}
return number;
}
^ top
Exercise 9.3
In this exercise we explore the use of try-catch statements
Specifications
- Save the following code file as
SumInput.java.
- Add try and catch statements that handle input errors.
- Submit your updated
SumInput.java file along with your other exercises for this lesson.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import java.util.*;
public class SumInput {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double data = 1.0;
double sum = 0.0;
while (data != 0.0) {
System.out.print("So far, sum = " + sum
+ "\nEnter a number or 0 to exit: ");
data = input.nextDouble();
sum = sum + data;
}
System.out.println("Ending sum: " + sum);
}
}
|
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Course info
Help
| FAQ's
| HowTo's
| Links
Last Updated: October 25 2005 @19:53:34
|