## Roots of a Quadratic Equation

### Overview

You are going to write a program which solves for the roots of a quadratic equation using the well know formula: In this assignment you will do a number of things:

• declare variables and assign values to them

• do mathematical calculations using variables

• declare methods

• call methods

• pass values to methods

• return values from methods

• read code and analyze it for errors

The completed assignment will consist of two things:

1. A `Java` program to compute the roots

### Understanding Methods

A method is a name given to one or more statements that performs some work on behalf of the code that calls it. To use it, the calling code simply uses its `name()` and the statements in the method are executed. Methods provide abstraction in the code, replacing the details of how the method does its work (the actual code) by a name which conveys what the method does. Choosing good names for variables and methods is important.

Methods are useful because they allow the writer to decompose a problem into smaller parts (the methods), then call them to complete the necessary work. Methods may be reused over and over again, simplifying the creation of more complex programs. Furthermore, one can call a method and defer the actual details of its implementation until later. One can concentrate on the big picture first, then take care of details later.

Methods may have parameter(s). For example the method `Math.sqrt()` takes a single parameter (a number), then calculates its square root. The user need not be concerned with how `Math.sqrt()` actually does its work. The user only cares what `Math.sqrt()` does.

Methods may return values (e.g. `Math.sqrt()`) or be `void` (e.g. `System.out.println()`). Methods that return values are "answering questions".

## Part A - The base program

### Getting Started

2. Create a new Project named `P2` (`File → new → Java Project`)

3. Create a new class named `QuadEqn`. (`File → new → Class`). Check the box that tells Eclipse to create `public static void main(String[] args)`. Then press the `Finish` button. Eclipse will create a new class with an empty `main()` method.

4. Put your name at the top of the file in a `Java` comment.

### The `main()` method

In your `main()` method declare three `double` variables. You may give them any names you want (`foo`, `bar`, `baz`). BUT, as we are working on quadratic equations, it is probably better if you name them `a`, `b`, and `c` because that is the nomenclature used in the formula.

1. Declare a `double` variable named `a` and assign it the value 6.0

2. Declare a `double` variable named `b` and assign it the value 12.0

3. Declare a `double` variable named `c` and assign it the value -48.0

4. Declare a `double` variable named `rad` and assign it the value `radical(a, b, c)`. What you are doing is calling a method and passing it three parameters. The result returned by the method is assigned to the variable.

Notice how the call to `radical(a, b, c)` is underlined in red. This is because Eclipse understands that you are making a method call, but it can not find any method named `radical()`. If you put the mouse over the underlined method name, Eclipse will explain the problem and offer you a quick fix. Take the suggested fix.

You are now ready to calculate and print the roots of the quadratic equation. Again, you are going to delegate the work to a method.

1. Write code to call the method `printRoot()` passing the parameters `a`, `b`, and `rad` You should see that the method name `printRoot()` is underlined in red. Allow Eclipse to create an empty implementation for you.

2. Write another line to call `printRoot()` a second time to print the other root. You should only need to add a single character to the code you wrote in the previous line.

At this point, you have a complete program, but the two methods have only skeleton implementations. This means that they will execute but will not do their intended job. The importance of this is that you can actually run your program and incrementally implement/test the methods one at a time.

### The `radical()` method

You are now ready to implement `radical()`. The purpose of this method is to calculate the square root of the expression under the square root sign.

1. Declare a `double` variable (select some name) and assign it to the square root of the expression shown in the formula. Note that the `radical()` method has three parameters passed in and you can simply use their names in the equation. To find the square root, use the method `Math.sqrt()`. You may use a single line of code or break it into multiple statements for the sub expressions.

2. Add a `System.out.println()` and print the value you calculated.

3. Modify the `return` statement to return the variable you created in the previous step(s) instead of `0`.

Now test your program by running it. Your program should print the value `radical() → 36.0`. What you are doing is testing what you just completed. A best practice is to write a little code, test it until it is correct, and then repeat. At the end you will have a working program because you have tested each part along the way. Once you are certain your method works, you may comment out or remove the `System.out.println()`.

### The `printRoot()` method

This routine will calculate a single root and print it.

1. declare a double variable and assign it to the root obtained by the addition in the formula.

2. Add a `System.out.println()` to print the root prefaced by the string `Root: `.

Now run your program again. You should see `Root: 2.0` and `Root: -4.0`.

You are DONE! However, your program only calculates the roots of a single quadratic equation. To calculate the roots of a different equation, you must modify the program and rerun it. Not very friendly for the user. So, lets fix that.

### Generalizing `QuadEqn`

Did you notice that the `main()` method has parameters? We can easily take advantage of this to calculate the roots of any quadratic equation. We can pass the coefficients of the quadratic equation to `main()` so it is more useful. The declaration of `main()` is

`  public static void main(String[] args)`

The notation `String[]` means that the variable `args` is an array. An array is a type of variable that hold multiple values. Individual values in the array are accessed using an integer index. For example, if one considers a list of planets ordered by their distance from the sun, Mercury is the 1st and Earth is the 3rd planet. In computer arrays, the index starts at 0 rather than the 1 that humans typically use to denote the 1st element in a list. The syntax for accessing an individual value is `variable[index]` where index can be a number (e.g. `0`), a variable (e.g. `i`), or even an expression (e.g. `i+1`).

Since values are passed into `main()`, how do we actually use them in the method?

1. Replace the value assigned to `a` by `args`.

2. What happens when we do this?

3. Can we use any of the suggested quick fixes? Why not?

The problem is that `a` is a `double`, but `args` is a `String`. So, you need to convert the string containing the characters `6` `.` `0` into the number `6.0`. Fortunately, Java has a class `Double` (capital D intensional) that can help us. Find a method in the documentation that takes a `String` as an argument and return a `double`. Use the method you found and call it passing the parameter `args`. Since this method is a `static` method in a different `class`, you need to preface the call with the class name (e.g. `Double.methodName(args`).

Now fix the assignments for variables `b` and `c`.

### Passing values to `main()`

To pass values to the `main()` method in Eclipse do the following:

1. Bring up the configuration menu by selecting `run → Run configurations…​`.

2. Select the tab labeled `Arguments`

3. In the box labeled `Program Arguments` type in numeric values for the three coefficients `a`, `b`, and `c`.

### Final steps

Run your program multiple times with different parameters. There are at least three situations that will produce unexpected results. Some may result in `Exception`. Others may produce strange output.

Now add an `Answers` section to your code as a `Java` block comment.

1. As Java comments prior to the line `public class QuadEqn`, describe three ways to create problems for you program. If following your description causes an `Exception`, give the exact name of the exception.

```  /* Answers
1. If the users does ... this results in ...
2.
3.
*/```

Use the `Checkin` tab on the class web site and turn in the file `QuadEqn.java`.

## PART B - Prompting the user for input

In Part B, you will modify your code to allow the user to enter the coefficients from the keyboard. Your code will prompt the user to enter a value and then when the user enters a value (followed by the `Enter` key), the value will be assigned to a variable.

### Using a `Scanner` for keyboard input

In order to read from the keyboard, you must use the methods of an object designed to do just that. One way is to use a class called `Scanner`. Add the following line as the first line of `main()`.

`  Scanner kbd = new Scanner(System.in);`

This statement is declaring a variable of type `Scanner`, named `kbd`. It is then initializing it by creating a `new` one and initializing this using the value `System.in`. One we have created `kbd` we can use it to access things that the user typed in. You can create a `Scanner` to read the contents of a text file or to read other sources of information. In `Java` the variable `System.in` represents the keyboard. It is used for input. `System.out` is used for output to the screen. You used this when you wrote `System.out.println()`. The method `println()` is a method of the variable `System.in`.

### Using a method to collect input

So now you need to use the `Scanner` to actually get values from the users. This is a good place for a method. Add the following line to `main()` just after your declaration of `kbd`. What you are doing is saying that `args` will be initialized by reading from the keyboard, rather that externally.

`   args = getCoefficients(kbd);`

Again you will see that `getCoefficients()` is underlined in red. As you did earlier, place the mouse over the underlined code, and see what quick fix is available. Allow Eclipse to create the method for you.

### Implementing `getCoefficients()`

Notice that `getCoefficients()` is responsible for returning an array of `String`. We can tell that by the `[]` notation. Furthermore, we know that our program requires three strings, each of which contains one of the coefficients for the quadratic equation. So this method will build the array of values, but delegate the actual input to yet another method.

1. Declare a `String` variable and initialize it with the result of calling `getCoefficient("a", kbd)`. What do you thing the `"a"` is going to be used for?

2. Declare two more `String` variables and assign values in the same way.

3. Now that you have collected the three coefficients, we must package them in an array to `return` to the caller. Java makes it easy to declare and initialize an array in a single step. Use the following pattern to create a `String[]` array.

4. Return this variable by modifying the `return` statement.

`  type[] variable-name = { list-of-values-separated-by-commas };`

### Implementing `getCoefficient()`

Notice that when Eclipse created the empty implementation of `getCoefficient()` that it named the first parameter `string` (note lower case). Since your call passed a literal (e.g. `"a"`), instead of a variable, Eclipse chose a simple name that really doesn’t convey what the parameter is used for. The parameter will be used to prompt the user which coefficient to enter. To make this clearer, change the name of the first parameter to `prompt`.

A prompt like `"a"` is not, by itself, very useful. Wouldn’t it be better to give a more complete prompt to the user? There are two ways you might do this:

1. Pass a longer prompt in the call.

2. Compose a longer prompt incorporating the parameter.

You will do the latter to print a prompt for the user like the following. Note that the prompt should be on the same line as what the user types.

`  Enter coefficient X: <user types value here>`

To complete the routine, you will use the `kbd.nextLine()` method to take a value from the keyboard and assign it to a `String` variable. You will then modify the `return` statement to actually return the variable.

## Part C - Choices and Error Handling

In Part B, you replaced using command line parameters to `main()` by prompting the user for input. In this version, you will give the user the ability to use either method. You will also add some error checking.

The call to `main()` will always get a non-null value for `args`. But how can you tell if the user actually passed any command line parameters?

1. Write some simple debugging code as the first line of `main()` to examine `args` under different conditions. What is the answer?

2. Using your new found knowledge, add an `if` statement encapsulating the prompt code to only execute under appropriate conditions.

3. Add some more code to determine if the correct number of parameters was passed to `main()`. If not, call them method `usage()`. This is a unix style of telling the user how to run the program if they ran it incorrectly. Again, defer the implementation of `usage()`.

4. Add code to test the value of the `a` coefficient to verify it is not zero. If it is, call `usage()`.

### Implementing `usage()`

The idea of a `usage` statement is to give the user a brief description of how to run the program. It is not a replacement for a manual, but serves to remind the user how to use the program. After the `usage` is given, the program normally terminates itself. To implement the `usage()` method:

1. Add output that describes how the user may run the program. All output goes to `System.err` instead of the `System.out`. All the methods you have used with `System.out` are also available to `System.err`.

2. Describe the two variations of how to run the program

3. Define any constraints on the values.

4. Terminate the program using `System.exit(1);`. A non-zero exit is the unix convention of signaling an error to the outside world. Zero means successful completion; non-zero signals error (potentially defining the type of error by the number).

### Handling non-numeric inputs

Run your program, but use a non-numeric value for a coefficient. What did you observe and where did the error occur? A crashing program is not very friendly to the user. That is why the check for a non-zero value of the coefficient `a` is important.

To handle this type of error, you must do some checking before invoking the code to convert the `String` to a `double`. This most easily done by adding a level of indirection in the code. Instead of calling `Double.parseDouble()` directly, replace it by a call to a new method you write. Name this method `getDouble()` and create an empty implementation. Note that in doing this, the basic structure of `main()` has not changed at all. Only the detail of numeric conversion has changed.

### Implementing `getDouble()`

Like the method `Double.parseDouble()` your method `getDouble()` takes a `String` as a parameter and returns a `double`. As part of its implementation it will actually use `Double.parseDouble()` to do the work. But, before that it needs to validate that the input parameter (a `String`) really does represent a `double`.

The Jave `Scanner` class that you used earlier provides this capability. The general flow of the function is:

1. Define a new `Scanner` variable initialized using the parameter of the method.

2. Use one of the `Scanner` methods to determine if there is a double in the string. Hint: look for method that begins with the prefix `hasNext`.

3. If there is a `double`, extract if from the `Scanner` variable.

4. If there is not, print out a message to `System.err` indicating the given string is not a number and exit using `usage()`.

5. Now verify if another token was entered by using the `Scanner` method `hasNext()`. If it does, print out a message indicating the problem and exit using `usage()`.

6. Lastly, if all error checks pass, return the `double` value to the caller.

### Error handling during keyboard input

Your program terminates whenever an error condition is encountered. In the case of interactive use, it would be useful to allow the user to correct the mistake, rather that having to start over. Recall that interactive input uses the method `getCoefficient()`.

Add some code to `getCoefficient()` to verify that what the user entered is valid. Notice that this will be almost identical to what you did in `getDouble()`, except that you don’t want to terminate the program. Instead, print the error for the user, then print a new prompt and get a revised value.

Perhaps you can take most of the code out of `getDouble()` and put it in a `boolean` method the determines if the `String` is really a `double` and return a `true/false` result. Boolean methods often begin with the prefix `is` so that an `if` statement invoking it looks like `if (isXXX())`. You may invoke your new method from both `getDouble()` and `getCoefficient()`. Each of these method will ultimately do something different depending on the return value, but use a common method to determine if there are any errors.

## Part D - Imaginary Solutions

Not all value for the coefficients of a quadratic equation result in real values for solutions. Under some conditions, the roots will be imaginary. In this case the roots are represented as complex numbers. See this page for how complex roots are written.

Your task is to modify your program to handle such situations without error. It will likely involve modifying `printRoot()` to handle both real and imaginary roots, or creating a second method to handle imaginary roots. The choice is yours. What else do you need to change?