I'm having a problem with my Java assignment. I'm getting an unexpected exception, specifically:
java.util.NoSuchElementException: No line found
I am using Scanner(System.in) and the program is continually reading nothing and repeating the "invalid format" exception text. If I enter a correctly valued int, the first part passes and then the double part immediately goes into this exception. If I enter an incorrectly valued int, then it starts looping the exception.
Here is my code:
import java.util.Scanner;
public class Program_4 {
public static void main(String[] args) {
getValidInt("Enter an integer from 5 to 50",5,50);
getValidDouble("Enter a double from 5.0 to 50.0",5.0,50.0);
getValidString("Enter a string with length from 5 to 8 characters",5,8);
}
public static int getInt(String prompt)
{
Scanner sc = new Scanner(System.in);
int i = 0;
boolean isValid;
do
{
try
{
System.out.print(prompt + ": ");
i = Integer.parseInt(sc.nextLine());
isValid = true;
}
catch (Exception e)
{
System.out.println(e);
System.out.print("Invalid Format: ");
isValid = false;
}
}
while (isValid == false);
sc.close();
return i;
}
public static int getValidInt(String prompt, int min, int max)
{
int i = 0;
boolean isValid = false;
do
{
i = getInt(prompt);
if(i < min) System.out.println("Value must be >= " + min);
else if(i > max) System.out.println("Value must be <= " + max);
else isValid = true;
} while (isValid == false);
return i;
}
public static double getDouble(String prompt)
{
Scanner sc = new Scanner(System.in);
double i = 0.0;
boolean isValid;
do
{
try
{
System.out.print(prompt + ": ");
i = Double.parseDouble(sc.nextLine());
isValid = true;
}
catch (Exception e)
{
System.out.println(e);
System.out.println("Invalid Format: ");
isValid = false;
}
} while (isValid == false);
sc.close();
return i;
}
public static double getValidDouble(String prompt, double min, double max)
{
int i = 0;
boolean isValid = false;
do
{
i = getInt(prompt);
if(i < min) System.out.println("Value must be >= " + min);
else if(i > max) System.out.println("Value must be <= " + max);
else isValid = true;
} while (isValid == false);
return i;
}
public static String getString(String prompt)
{
Scanner sc = new Scanner(System.in);
String i="";
boolean isValid;
do
{
try
{
System.out.print(prompt + ": ");
i = sc.nextLine();
isValid = true;
}
catch (Exception e)
{
System.out.print("Invalid Format: ");
isValid = false;
}
} while (isValid == false);
sc.close();
return i;
}
public static String getValidString(String prompt, int min, int max)
{
String i;
boolean isValid = false;
do
{
i = getString(prompt);
if(i.length() < min) System.out.println("String must be more than " + min + " characters.");
else if(i.length() > max) System.out.println("String must be more than " + max + " characters.");
else isValid = true;
} while (isValid == false);
return i;
}
}
You have more than one Scanner that you close, which closes the underlying InputStream, therefore another Scanner can no longer read from the same InputStream and a NoSuchElementException results.
For console apps, use a single Scanner to read from System.in.
Since you print out the same message in all three places where an exception is caught, it is difficult to say with any certainty what is going on:
Use printStackTrace() to find out where the exception is happening
Don't catch Exception like that. Catch the exceptions that you are expecting and that your code is designed to handle. If you catch Exception you could end up catching all sorts of unexpected exceptions (NPE, end of file, etc) ... and incorrectly reporting them as "Invalid format".
Related
I am practicing using the try-catch block to validate user input. Trying so hard to do but don't know why it doesn't work. I tried it both ways. It always pops out InputMismatchException and end the program.
The first one, I followed this video: https://www.youtube.com/watch?v=PWez5mVXACc&t=356s
public int moveStone(int initialStone, int upperBound, int stoneBalance) throws Exception {
int takeStone = 0;
boolean isNumber = false;
do {
if (in.hasNextInt()){
takeStone = in.nextInt();
isNumber =true;
}
if (!in.hasNextInt()) {
if (stoneBalance >= upperBound) {
System.out.println("Invalid move. You must remove between 1 and " + upperBound + " stones.\n");
isNumber = false;
takeStone = in.nextInt();
}
if (stoneBalance < upperBound) {
System.out.println("Invalid move. You must remove between 1 and " + stoneBalance + " stones.\n");
isNumber = false;
takeStone = in.nextInt();
}
}
} while (!(isNumber));
return takeStone;
}
and this, I followed by other tutorials:
public int moveStone(int initialStone, int upperBound, int stoneBalance) throws Exception {
int takeStone = 0;
try {
if (in.hasNextLine()) {
throw new Exception();
} else {
takeStone = in.nextInt();
return takeStone;
}
} catch (Exception e) {
System.out.println("Invalid move");
if (stoneBalance >= upperBound) {
System.out.println("You must remove between 1 and " + upperBound + " stones.\n");
takeStone = in.nextInt();
return takeStone;
}
if (stoneBalance < upperBound) {
System.out.println("You must remove between 1 and " + stoneBalance + " stones.\n");
takeStone = in.nextInt();
return takeStone;
}
}
return -1;
}
You are throwing Exception
if (in.hasNextLine()) {
throw new Exception();
}
And catching only InputMismatchException. Use Exception in catch
catch (Exception e){
I got where the problem is: the user input still remains in the Scanner buffer.
When it passes the invalid input, it goes to the catch block. This operation is correct.
However, when the program has to prompt the user to give another input, the invalid input still in the Scanner that it goes straight to the takeStone = in.nextInt(). The program jumps out because of InputMismatchException directly.
The solution is to put another Scanner to take the token before prompting the user input.
public int moveStone(int initialStone, int upperBound, int stoneBalance) throws Exception {
int takeStone = 0;
try {
if (!in.hasNextInt()) {
throw new Exception();
} else {
takeStone = in.nextInt();
return takeStone;
}
} catch (Exception e) {
if (stoneBalance >= upperBound) {
System.out.println("Invalid move. You must remove between 1 and " + upperBound + " stones.\n");
in.next(); // input still in the Scanner buffer, use another scanner to take this input
takeStone = in.nextInt();
return takeStone;
}
if (stoneBalance < upperBound) {
System.out.println("Invalid move. You must remove between 1 and " + stoneBalance + " stones.\n");
in.next();
takeStone = in.nextInt();
return takeStone;
}
}
return -1;
}
Im trying to write this class copied from my textbook. From what i understand, I copied the code exactly as it appeared, with minor changes to variable names. But when I do anything, the two lines number = getInt(Sc3, prompt); and d = getDouble(sc3, prompt); throw errors that say "no suitable method found for getInt/getDouble(Scanner, String). Why is this and what can I code to fix this? The surrounding code below.
import java.util.Scanner;
public class Console {
private static Scanner sc3 = new Scanner(System.in);
public static String getString(String prompt) {
System.out.print(prompt);
String s = sc3.next();
sc3.nextLine();
return s;
}
public static int getInt(String prompt) {
int number = 0;
boolean isValid = false;
while (isValid) {
System.out.print(prompt);
if (sc3.hasNextInt()) {
number = sc3.nextInt();
isValid = true;
}else {
System.out.println("Error! Entry must be an integer. Please try again.");
}
sc3.nextLine();
}
return number;
}
public static int getInt(String prompt, int minimum, int maximum) {
int number = 0;
boolean isValid = false;
while (!isValid) {
number = getInt(sc3, prompt);
if (number <= minimum) {
System.out.println("Error. User entry nust be greater than" + " " + minimum + " " + ".");
} else if (number >= maximum) {
System.out.println("Error. User entry must be less than" + " " + maximum + " " + ".");
} else {
isValid = true;
}
}
return number;
}
public static double getDouble(String prompt) {
double d = 0;
boolean isValid = false;
while (!isValid) {
System.out.print(prompt);
if (sc3.hasNextDouble()) {
d = sc3.nextDouble();
isValid = true;
} else {
System.out.println("Error. Invalid number. Try again.");
}
sc3.nextLine();
}
return d;
}
public static double getDouble(String prompt, double minimum, double maximum) {
double d = 0;
boolean isValid = false;
while (!isValid) {
d = getDouble(sc3, prompt);
if (d <= minimum) {
System.out.println("Error. Number must be greater than" + minimum + ".");
}else if (d >= maximum) {
System.out.println("Error. Number must be less than" + maximum + ".");
}else {
isValid = true;
}
return d;
}
}
}
The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures. This means that methods within a class can have the same name if they have different parameter lists
from here
So you are missing the getInt(Scanner Sc3, String prompt) and getDouble(Scanner sc3, String prompt) methods.
I wrote a simple program.it gets two Integer number from user and return odd numbers to user.i validate them to force the user to type just Integer numbers.
when user type other data type,program gives him my custom error.that is right up to now but when this happen user has to type inputs from the beginning.it means that program takes the user to the first home.
here is my main class :
package train;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Calculate cal = new Calculate();
Scanner input = new Scanner(System.in);
int number1 = 0;
int number2 = 0;
boolean isNumber;
do {
System.out.println("enter number1 please : ");
if (input.hasNextInt()) {
number1 = input.nextInt();
isNumber = true;
System.out.println("enter number2 please : ");
}
if (input.hasNextInt()) {
number2 = input.nextInt();
isNumber = true;
} else {
System.out.println("wrong number!");
isNumber = false;
input.next();
}
} while (!(isNumber));
cal.setNumbers(number1, number2);
cal.result();
input.close();
}
}
and here is my calculate class which return odd numbers :
public class Calculate {
private int minNumber;
private int MaxNumber;
public void setNumbers(int min, int max) {
this.minNumber = min;
this.MaxNumber = max;
}
public void result() {
int count = 0; // number of results
ArrayList<Integer> oddNumber = new ArrayList<Integer>(); // array of odd numbers
// get odd numbers
for (int i = minNumber; i < MaxNumber; i++) {
if ((i % 2) != 0) {
oddNumber.add(i);
count++;
}
}
int i = 0;// counter for printing array
while (i < oddNumber.size()) {
if(i != oddNumber.size()){
System.out.print(oddNumber.get(i) + ",");
}else{
System.out.println(oddNumber.get(i));
}
i++;
}
// print result numbers
System.out.println("\nResult number : " + count);
// print number range
System.out.println("You wanted us to search between " + minNumber
+ " and " + MaxNumber);
}
}
Create a method verifyAndGetNumber which will verify a number with regex \d+ which means match one or more digit. Throw Exception if it is not number. Catch the exception and print your custom message.
public static void main(String[] args) {
Calculate cal = new Calculate();
Scanner input = new Scanner(System.in);
int number1 = 0;
int number2 = 0;
boolean isNumber = false;
do {
try {
System.out.println("enter number1 please : ");
if (input.hasNextLine()) {
number1 = verifyAndGetNumber(input.nextLine());
}
System.out.println("enter number2 please : ");
if (input.hasNextLine()) {
number2 = verifyAndGetNumber(input.nextLine());
}
isNumber = true;
} catch (Exception e) {
System.out.println(e.getMessage());
}
} while (!isNumber);
cal.setNumbers(number1, number2);
cal.result();
input.close();
}
private static int verifyAndGetNumber(String line) throws Exception {
if (line.matches("\\d+")) {
return Integer.parseInt(line);
}
throw new Exception("wrong number!");
}
You can count the number of Integer inputs entered by the user and that way you can solve the problem.
So you can modify the code as:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Calculate cal = new Calculate();
Scanner input = new Scanner(System.in);
int number1 = 0;
int number2 = 0;
boolean isNumber;
int totalEnteredNumbers=0;
int currNumber=1;
do {
System.out.println("enter number"+currNumber+" please : ");
if (totalEnteredNumbers==0 && input.hasNextInt()) {
number1 = input.nextInt();
isNumber = true;
currNumber++;
System.out.println("enter number"+currNumber+" please : ");
totalEnteredNumbers++;
}
if (totalEnteredNumbers==1 && input.hasNextInt()) {
number2 = input.nextInt();
isNumber = true;
} else {
System.out.println("wrong number!");
isNumber = false;
input.next();
}
} while (!(isNumber));
cal.setNumbers(number1, number2);
cal.result();
input.close();
}
}
Anyways here you can also remove the boolean variable isNumber from termination condition by replacing it with while(totalEnteredNumbers<2);.
However this can also be solved with the following code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Calculate cal = new Calculate();
Scanner input = new Scanner(System.in);
int number1 = 0;
int number2 = 0;
boolean numberTaken=false;
while(!numberTaken)
{
System.out.print("Enter number1 : ");
String ip=input.next();
try
{
number1=Integer.parseInt(ip); //If it is not valid number, It will throw an Exception
numberTaken=true;
}
catch(Exception e)
{
System.out.println("Wrong Number!");
}
}
numberTaken=false; //For second input
while(!numberTaken)
{
System.out.print("Enter number2 : ");
String ip=input.next();
try
{
number2=Integer.parseInt(ip); //If it is not valid number, It will throw an Exception
numberTaken=true;
}
catch(Exception e)
{
System.out.println("Wrong Number!");
}
}
cal.setNumbers(number1, number2);
cal.result();
input.close();
}
}
This question already has answers here:
What is the reason behind "non-static method cannot be referenced from a static context"? [duplicate]
(13 answers)
Closed 9 years ago.
I'm working with two classes. One is called Validator and one is called LineItemApp.
Here is the code for the Validator class.
import java.util.Scanner;
public class Validator
{
public String getString(Scanner sc, String prompt)
{
System.out.print(prompt);
String s = sc.next(); // read user entry
sc.nextLine(); // discard any other data entered on the line
return s;
}
public int getInt(Scanner sc, String prompt)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextInt())
{
i = sc.nextInt();
isValid = true;
}
else
{
System.out.println("Error! Invalid integer value. Try again.");
}
sc.nextLine(); // discard any other data entered on the line
}
return i;
}
public int getInt(Scanner sc, String prompt,
int min, int max)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
i = getInt(sc, prompt);
if (i <= min)
System.out.println(
"Error! Number must be greater than " + min + ".");
else if (i >= max)
System.out.println(
"Error! Number must be less than " + max + ".");
else
isValid = true;
}
return i;
}
public double getDouble(Scanner sc, String prompt)
{
double d = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextDouble())
{
d = sc.nextDouble();
isValid = true;
}
else
{
System.out.println("Error! Invalid decimal value. Try again.");
}
sc.nextLine(); // discard any other data entered on the line
}
return d;
}
public double getDouble(Scanner sc, String prompt,
double min, double max)
{
double d = 0;
boolean isValid = false;
while (isValid == false)
{
d = getDouble(sc, prompt);
if (d <= min)
System.out.println(
"Error! Number must be greater than " + min + ".");
else if (d >= max)
System.out.println(
"Error! Number must be less than " + max + ".");
else
isValid = true;
}
return d;
}
}
Here is my LineItemApp class
import java.util.Scanner;
public class LineItemApp
{
public static void main(String args[])
{
// display a welcome message
System.out.println("Welcome to the Line Item Calculator");
System.out.println();
// create 1 or more line items
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y"))
{
// get the input from the user
String productCode = Validator.getString(sc,
"Enter product code: ");
int quantity = Validator.getInt(sc,
"Enter quantity: ", 0, 1000);
// get the Product object
Product product = ProductDB.getProduct(productCode);
// create the LineItem object
LineItem lineItem = new LineItem(product, quantity);
// display the output
System.out.println();
System.out.println("LINE ITEM");
System.out.println("Code: " + product.getCode());
System.out.println("Description: " + product.getDescription());
System.out.println("Price: " + product.getFormattedPrice());
System.out.println("Quantity: " + lineItem.getQuantity());
System.out.println("Total: " +
lineItem.getFormattedTotal() + "\n");
// see if the user wants to continue
choice = Validator.getString(sc, "Continue? (y/n): ");
System.out.println();
}
}
}
Any help would be greatly appreciated.
Thanks,
David
You need an instance of Validator, to enter the methods
// see if the user wants to continue
Validator validator = new Validator();
choice = validator.getString(sc, "Continue? (y/n): ");
System.out.println();
Or as suggested in another answer you can make Validator methods static, but this change sure is bigger and you have to change code, and you don't know if you use this validator in another part so im not agree but if you want to refactor it, is not at all bad idea cause your class Validator doesn't have state, only do some algorithms.
You are calling non-static methods from a static method (which is now main() ).
You can eliminate the error by declaring the methods arising the warning to static.
Your should understand what is the static method.
http://www.leepoint.net/notes-java/flow/methods/50static-methods.html
This applicaiton validates that the user is entering the correct data. I have about 95% of this done but I can not figure out the Continue? (y/n) part. If you hit anything but y or n (or if you leave the line blank) it is supposed to print an error:So this is what the application is supposed to look like in the console:
Continue? (y/n):
Error! This entry is required. Try again.
Continue? (y/n): x
Error! Entry must be 'y' or 'n'. Try again.
Continue? (y/n): n
Here is my code:
public static void main(String[] args) {
System.out.println("Welcome to the Loan Calculator");
System.out.println();
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y"))
{
System.out.println("DATA ENTRY");
double loanAmount = getDoubleWithinRange(sc, "Enter loan amount: ", 0, 1000000);
double interestRate = getDoubleWithinRange(sc, "Enter yearly interest rate: ", 0, 20);
int years = getIntWithinRange(sc, "Enter number of years: ", 0, 100);
double monthlyInterestRate = interestRate/12/100;
int months = years * 12;
double monthlyPayment = calculateMonthlyPayment(loanAmount, monthlyInterestRate, months);
NumberFormat currency = NumberFormat.getCurrencyInstance();
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(1);
String results = "Loan amount: \t\t" + currency.format(loanAmount) + "\n"
+ "Yearly interest rate: \t" + percent.format(interestRate/100) + "\n"
+ "Number of years: \t" + years + "\n"
+ "Monthly payment: \t" + currency.format(monthlyPayment) + "\n";
System.out.println();
System.out.println("FORMATTED RESULTS");
System.out.println(results);
String getContinue = getContinueWithinRange(sc, "Continue? (y/n): ", "y", "n");
System.out.print(getContinue);
System.out.println();
}
}
public static double getDoubleWithinRange(Scanner sc, String prompt, double min, double max)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
d = getDouble(sc, prompt);
if (d <=min) {
System.out.println("Error! Number must be greater than " + min + ".");
}
else if (d >= max) {
System.out.println("Error! Number must be less than " + max + ".");
}
else {
isValid = true;
}
}
return d;
}
public static double getDouble(Scanner sc, String prompt)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextDouble())
{
d = sc.nextDouble();
isValid = true;
}
else
{
System.out.println("Error! Invalid decimal value. Try Again.");
}
sc.nextLine();
}
return d;
}
public static int getIntWithinRange(Scanner sc, String prompt, int min, int max)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
i = getInt(sc, prompt);
if (i <= min) {
System.out.println("Error! Number must be greater than " + min + ".");
}
else if (i >= max) {
System.out.println("Error! Number must be less than " + max + ".");
}
else {
isValid = true;
}
}
return i;
}
public static int getInt(Scanner sc, String prompt)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if(sc.hasNextInt())
{
i = sc.nextInt();
isValid = true;
}
else
{
System.out.println("Error! Invalid integer value. Try again.");
}
sc.nextLine();
}
return i;
}
public static double calculateMonthlyPayment(double loanAmount, double monthlyInterestRate, double months)
{
double monthlyPayment = 0;
for (int i = 1; i <= months; i++)
{
monthlyPayment = loanAmount * monthlyInterestRate/(1 - 1/Math.pow(1 + monthlyInterestRate, months));
}
return monthlyPayment;
}
System.out.print(getContinue);
System.out.println();
public static String getContinueWithinRange(Scanner sc, String prompt, String yContinue, String nContinue)
{
String i = "";
boolean isValid = false;
while (isValid == false)
{
i = getContinue(sc, prompt);
if (!yContinue.equalsIgnoreCase("") && !nContinue.equalsIgnoreCase("")){
System.out.println("Error! Entry must be 'y' or 'n'. Try again.");
}
else{
isValid = true;
}
}
return i;
}
public static String getContinue(Scanner sc, String prompt)
{
String i = "";
boolean isValid = false;
while(isValid == false)
{
System.out.print(prompt);
if (i.length() > 0)
{
i = sc.nextLine();
isValid = true;
}
else
{
System.out.println("Error! Entry is required. Try again.");
}
sc.nextLine();
}
return i;
}
}
Change the content of the while loop in getContinue() to this:
System.out.print(prompt);
i = sc.nextLine();
if (i.length() > 0)
{
isValid = true;
}
else
{
System.out.println("Error! Entry is required. Try again.");
}
This first prints the prompt, then reads the input into the variable that will be returned, then checks whether the input had length greater than zero.
In getContinueWithinRange(), the condition in the if clause needs to be replaced by
!yContinue.equalsIgnoreCase(i) && !nContinue.equalsIgnoreCase(i)
This will "y" and "n" against the input instead of against "".
Also if you would like to actually continue after reading a "y", you need to do something like this:
if (!yContinue.equalsIgnoreCase(i) && !nContinue.equalsIgnoreCase(i)){
System.out.println("Error! Entry must be 'y' or 'n'. Try again.");
}
else {
isValid = true;
}
The first case catches invalid input, the second ends the loop if the user entered "n", the third tells the user the loop will continue after he entered a "y".
Finally, to make your program do what it's supposed to do, change
String getContinue = getContinueWithinRange(sc, "Continue? (y/n): ", "y", "n");
to
choice = getContinueWithinRange(sc, "Continue? (y/n): ", "y", "n");
in your main method.
I try something for you according to your first submitted code
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Tester4 {
public static String getContinueWithinRange(Scanner sc, String prompt, String yContinue, String nContinue) {
String result = "";
boolean isValid = false;
boolean isStarted = false;
while(!isValid) {
result = getContinue(sc, prompt, isStarted);
isStarted = true;
if(yContinue.equalsIgnoreCase(result) || nContinue.equalsIgnoreCase(result)) {
isValid = true;
} else if(!yContinue.equalsIgnoreCase(result) || !nContinue.equalsIgnoreCase(result)) {
System.out.println("Error! Entry must be 'y' or 'n'. Try again.");
} else {
System.out.println("Error! Entry must be 'y' or 'n'. Try again.");
}
}
return result;
}
public static String getContinue(Scanner sc, String prompt, boolean isStarted) {
String result = "";
boolean isValid = false;
while(!isValid) {
if(result.isEmpty() && !isStarted) {
System.out.print(prompt);
System.out.println("Error! Entry is required. Try again.");
}
result = sc.nextLine();
if(result.length() > 0) {
isValid = true;
}
}
return result;
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String getContinue = getContinueWithinRange(sc, "Continue? (y/n): ", "y", "n");
// to call the method
System.out.print(getContinue);
System.out.println();
}
// InputStream stream = this.getClass().getClassLoader().getResourceAsStream("/images/image.jpg");
// BufferedImage bufferedImage=ImageIO.read(stream);
// ImageIcon icon= new ImageIcon(bufferedImage);
}
import java.util.*;
import java.text.*;
public class LoanPaymentApp {
public static void main(String[] args)
{
System.out.println("Welcome to the Loan Calculator");
System.out.println();
Scanner sc = new Scanner(System.in);
String choice = "y";
while (!choice.equalsIgnoreCase("n"))
{
System.out.println("DATA ENTRY");
double loanAmount = getDoubleWithinRange(sc, "Enter loan amount: ", 0, 1000000);
double interestRate = getDoubleWithinRange(sc, "Enter yearly interest rate: ", 0, 20);
int years = getIntWithinRange(sc, "Enter number of years: ", 0, 100);
double monthlyInterestRate = interestRate/12/100;
int months = years * 12;
double monthlyPayment = calculateMonthlyPayment(loanAmount, monthlyInterestRate, months);
NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(1);
String results = "Loan amount: \t\t" + currency.format(loanAmount) + "\n"
+ "Yearly interest rate: \t" + percent.format(interestRate/100) + "\n"
+ "Number of years: \t" + years + "\n"
+ "Monthly payment: \t" + currency.format(monthlyPayment) + "\n";
System.out.println();
System.out.println("FORMATTED RESULTS");
System.out.println(results);
System.out.print("Continue? (y/n): ");
choice = sc.nextLine();
while (!choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n"))
{
if (choice.equals(""))
{
System.out.println("Error! This entry is required. Try again.");
System.out.print("Continue? (y/n): ");
}
else
{
System.out.println("Error! Entry must be 'y' or 'n'. Try again.");
System.out.print("Continue? (y/n): ");
}
choice = sc.nextLine();
}
}
}
public static double getDoubleWithinRange(Scanner sc, String prompt, double min, double max)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
d = getDouble(sc, prompt);
if (d <=min) {
System.out.println("Error! Number must be greater than " + min + ".");
}
else if (d >= max) {
System.out.println("Error! Number must be less than " + max + ".");
}
else {
isValid = true;
}
}
return d;
}
public static double getDouble(Scanner sc, String prompt)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextDouble())
{
d = sc.nextDouble();
isValid = true;
}
else
{
System.out.println("Error! Invalid decimal value. Try Again.");
}
sc.nextLine();
}
return d;
}
public static int getIntWithinRange(Scanner sc, String prompt, int min, int max)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
i = getInt(sc, prompt);
if (i <= min) {
System.out.println("Error! Number must be greater than " + min + ".");
}
else if (i >= max) {
System.out.println("Error! Number must be less than " + max + ".");
}
else {
isValid = true;
}
}
return i;
}
public static int getInt(Scanner sc, String prompt)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if(sc.hasNextInt())
{
i = sc.nextInt();
isValid = true;
}
else
{
System.out.println("Error! Invalid integer value. Try again.");
}
sc.nextLine();
}
return i;
}
public static double calculateMonthlyPayment(double loanAmount, double monthlyInterestRate, double months)
{
double monthlyPayment = 0;
for (int i = 1; i <= months; i++)
{
monthlyPayment = loanAmount * monthlyInterestRate/(1 - 1/Math.pow(1 + monthlyInterestRate, months));
}
return monthlyPayment;
}
}