## Assignment 04

Repeat A02, only this time ask the user for the radius and height and use static methods to do the calculations.

Textbook: 2.6; 4.4; 10.1 - 10.3
New concepts: Input, `Scanner`; defining methods; exception handling (`try`/`catch`).

### Steps

Write a program that asks the user to enter the radius and height of a cone, and then print out its details. Print out the radius and height entered, as well as the slant height, volume, lateral surface area, and total surface area. See A02 if you need to review the necessary formulas.

#### Step 1: Methods

It would be nice to be able to reuse these calculations for other cones, much in the way you reuse the methods written in the `Math` class. Write the following static methods in your class:

• public static double getSlantHeight(double r, double h)
• public static double getVolume(double r, double h)
• public static double getLateralSurfaceArea(double r, double h)
• public static double getTotalSurfaceArea(double r, double h)

Remember that, as separate methods, these definitions will be in your class but outside of the main method. You will need to provide the `{bodies}` for these methods that do the appropriate calculation in each case and returns the result. Ideally, the calculation of each detail will occur in only one place in your code, in the relevant method. The methods should not print anything to the screen.

You can name the parameters whatever you want. For example, you could name the first parameter `radius` intead of `r`, if you prefer. These parameter names have nothing to do with the variable names you use in main. They can be the same or different.

However, everything else about of the method does matter. Make sure you name the methods exactly as shown, as Tamarin will be trying to call them directly, passing different values than you used when you call them from your main method. Note also that the two parameters are the same for all methods: the value of the radius, followed by the value of the height (never the slant height!). So, though you may rename the variables, you must not change the fact that each method takes the radius and the height, in that order.

You may find it useful to call one method from another. For example, you might call `getSlantHeight` from within `getLateralSurfaceArea` so that you don't have to repeat the calculation for the slant height.

#### Step 2: Main method

Call the four methods you wrote from your main method. The methods will now perform the calculations for you, so you don't need to repeat them in main.

In this assignment, your cone methods are in the same file as the main method, and you will probably only call each method once from main. However, note how it would be much easier to calculate the details of multiple cones by calling the methods multiple times using different values for the parameters (instead of writing out the formulas each time). Also, you could now reuse these methods in another program, even calling these methods from a main method written in a different class/file.

At this point, you should be able to compile and run your program and get the same input as for A02.

#### Step 3: User Input

Now add to the main method to prompt the user to enter a radius and height to use for the calculations. These should still be `double`s. Use a try/catch block so that your program ends gracefully (rather than crashing) if the user enters a String when you ask for a number. Your program should not try to print out the radius or other calculated details if the user did not correctly enter a number. (Note: This is labelled as Step 3, but you can do it first if you want to.)

#### Sample Output

User input is highlighted in green. Note that I ran this program three times; the command prompt line at the start of each run is not part of the program's output.

```D:\TA\grading\A04>java ZtomaszeA04
Enter the radius of a cone: 30
Enter the height of the cone: 40.00

For a right circular cone with radius 30.0 and height 40.0:
Slant height = 50.0
Volume = 37699.11184307752
Lateral surface area = 4712.38898038469
Total surface area = 7539.822368615503

Sorry, but you must enter a valid decimal number.

Enter the radius of a cone: 1.2
Enter the height of the cone: 3.4

For a right circular cone with radius 1.2 and height 3.4:
Slant height = 3.605551275463989
Volume = 5.127079210658542
Lateral surface area = 13.592608078966773
Total surface area = 18.116501500136074
```

### What to Submit

Upload your `UsernameA04.java` file to Tamarin.

1 - Compiles
Your program compiles successfully (no errors)
1.4 - Robust `main`
You read in the radius and then the height from the user as doubles and clearly print the labelled results returned by the four methods (0.8). Your program does not crash (but instead ends gracefully with only an error message) when given strings instead of numbers (0.6).
1.6 - Methods
Methods are named as above and each returns the correct result when passed a cone's radius and height value (given in that order). (0.4 each)

### FAQs

Example?
As an example of using try/catch, here is an updated version of A01's ZtomaszeAge.java: SafeUserAge.java. This version will not crash when the user enters something other than a number when requested. It also uses methods to print the details.
Do I have to prevent the user from entering 0 or a negative number?
No, this is not required. (You can do so if you want to, though. You'll have to use an if statement to do it--which we won't learn until next week.)
How do I use an exception to catch negative numbers?
You don't. (In fact, you can't.)

The only time you're going to get an exception from your `Scanner` is when you ask for a number and the user enters something else. (And the only way to handle this situation is by catching the `InputMismatchException`. You can't use an `if` here because, if the user enters a String rather than a number, the call to `nextDouble()` never even returns.)

Now, once you've successfully read in a number, your particular program might have additional requirements on the format: only even numbers, only something between 1 and 10, or only a number > 0. This you have to test using an `if` after you successfully read in the number. (You can't use an exception here; you have to test the number yourself with some sort of comparison operator.)
Is it okay if my answer is very very close to the correct answer but not exactly the same?
Yes, that's fine.

The reason for this is how `double`s are stored internally. They are only precise to a certain number of decimal places and, depending on which math operations you perform on them and in which order, that last decimal place may get rounded a digit or two either way along the way. For example, consider the following:

```    System.out.println(0.3);      //prints: 0.3
System.out.println(0.1 * 3);  //prints: 0.30000000000000004
```

This is always a danger with `double` math. This will be even more true when we get to the `==` (equality) operator next week.

There is a way to format floating point numbers when you print them, so you don't always have to have a big ugly string of digits. However, the formatting either involves the use of an object (such as an instance of `java.text.DecimalFormat`), or else a rather arcane formatting code (for example: `System.out.printf("%.4f\n", volume)`). Have a look at the textbook (section 3.6) if you're interested in these.