import java.util.Scanner; import java.io.PrintStream; /** * A user interface for our Quadratic Solver * * @author P. Conrad * @version for CS10, lab04, UCSB, Spring 2009 */ public class QuadraticSolver { /** A main method for a user interface for a program to solve * Quadratic equations---even for complex roots * * @param args Not used for this program */ public static void main(String [] args) { Scanner in = new Scanner(System.in); boolean userWantsToContinue = true; while (userWantsToContinue) { QuadraticEqn q = getQuadraticEqnFromUser(in, System.out); if (q.hasDegenerateRoot()) System.out.println("One degenerate root: " + q.degenerateRoot()); else if (q.getA() == 0.0) { assert(q.getB()==0.0); System.out.println("Can't calcuate any roots: a is 0, and b is 0"); } else { switch (q.numRealRoots()) { case 0: System.out.println("Complex roots: " + q.complexRoot1() + " and " + q.complexRoot2() ); break; case 1: System.out.println("One real root: " + q.realRoot1()); break; case 2: System.out.println("Two real roots: " + q.realRoot1() + " and " + q.realRoot2()); break; } // end switch } // end else System.out.println("Do you want to calculate another equation? Y/N"); userWantsToContinue = getYesOrNoAsBoolean(in); } // end while loop System.out.println("Goodbye!"); } // end main /** Get a quadratic equation object by asking the user for * values for a, b, and c. Note: You should NOT do something like this directly in a constructor! * Instead, separate the user interface from the actual object construction, as done here. * * @param in A scanner object used to get the input from * @param out A PrintStream used to print out the messages on * @return A Quadratic Equation object, constructed based on the user input for a, b, c */ private static QuadraticEqn getQuadraticEqnFromUser(Scanner in, PrintStream out) { out.println("Please enter values for a quadratic equation below.\n\n"); double a = getDouble("a", in, out); double b = getDouble("b", in, out); double c = getDouble("c", in, out); return new QuadraticEqn(a,b,c); } /** Get a double value. This function abstracts away the whole "keep asking until you get it right", * and is also reslient to recovering from bad input---we say it is "robust". * * @param name The name of the value we will ask the user for * @param in A scanner object used to get the input from * @param out A PrintStream used to print out the messages on * @return a double value */ private static double getDouble(String name, Scanner in, PrintStream out) { double returnValue = 0; while (true) // infinite loop---we exit via "return" { out.print("Please enter a value for " + name + ":"); String theInput = in.nextLine(); try { returnValue = Double.parseDouble(theInput); return returnValue; // here is where we exit the loop } catch (Exception e) { out.println("Sorry, an error occurred: " + e); } out.println("Please try again!\n"); } } /** Ask a yes/no question, and return answer as a boolean * @param in a Scanner object to ask the question on * @return true if the first letter of the response is y or Y */ private static boolean getYesOrNoAsBoolean(Scanner in) { String response = in.nextLine().toLowerCase(); return response.startsWith("y"); } }