Trouble using for loop in my program - java

In my code I am having the user type in 3 things, and for the third input I ask for the number of years. However in my for loop I can't use the variable that I ask the user to input. For example if the user were to input "3", my code would do 15 years (which is the max).
double yearInvest;
double interRate;
double numOfYears = 3;
double amountBeforeTotal;
double amountTotal;
double years;
System.out.println("Compound Interest \n");
System.out.println("This program will print out a title table that will "
+ " display the amount of a yearly investment over a period of "
+ " up to 15 years. \n");
Scanner input = new Scanner(System.in);
System.out.println("Enter the yearly investment:");
yearInvest = input.nextDouble();
System.out.println("Enter the interest rate (%):");
interRate = input.nextDouble();
System.out.println("Enter the number of years:");
numOfYears = input.nextDouble();
for (years = 1; 15 >= years; years++) {
System.out.format("%-4s %22s %12s %8s \n ", "Year", "Amount in Account",
"Interest", "Total");
amountTotal = (yearInvest * (interRate / 100)) + yearInvest;
System.out.format("%-4.1f", years);
System.out.format("%18.2f", yearInvest);
System.out.format("%14.2f", interRate);
System.out.format("%15.2f", amountTotal);
}
P.S. I am still working on the code and it is not fully done. And I would also like some advice if possible.

System.out.println("Enter the number of years:");
numOfYears = input.nextDouble();
for (years = 1; 15 >= years; years++)
Your code is getting a user inputted numOfyears which for example would be 3, for your case. Your loop is from (1..15) no matter what, since your loop's 2nd parameter is: 15 >= years.
What you are looking for is (1..numOfYears)
System.out.println("Enter the number of years:");
numOfYears = input.nextDouble();
for (years = 1; years <= numOfYears; years++)
//...more code

There are a few things that I notice about your code that might not be exactly what you want.
Firstly you are storing all of your variables as doubles which are mainly used for storing floating point (i.e. numbers with a decimal place). In place of double it might be better to use int.
Next your for loop is always going to loop 15 times with years 1 to 15. If you want this to be only numOfYears times you should have a loop that compares to numOfYears
for (years = 1; years <= numOfYears; years++) {
//TODO
}
Lastly something that is quite important for coding and something that it is easy to ignore if teaching yourself is style.
for (years = 1; 15>=years; years++ ) {
System.out.format("%-4s %22s %12s %8s \n ", "Year", "Amount in Account", "Interest", "Total");
amountTotal = (yearInvest * (interRate / 100)) + yearInvest;
System.out.format("%-4.1f", years);
System.out.format("%18.2f", yearInvest);
System.out.format("%14.2f", interRate);
System.out.format("%15.2f", amountTotal);
}
This indentation gives a much clearer view of what is in your for loop and helps debugging and readablilty

You can try this if you want to print only 15 years interest rates.
for (years = 1; numOfYears >= years; years++) {
System.out.format("%-4s %22s %12s %8s \n ", "Year", "Amount in Account",
"Interest", "Total");
amountTotal = (yearInvest * (interRate / 100)) + yearInvest;
System.out.format("%-4.1f", years);
System.out.format("%18.2f", yearInvest);
System.out.format("%14.2f", interRate);
System.out.format("%15.2f", amountTotal);
if(years == 15) {
break;
}
}
This will print the interest of 15 years if user enters any number greater than 15 or else will print interest rates of all years if user enters number < 15.

Related

Java - How to Validate Numerical User Input Within A Certain Range Correctly

Just looking for a little help! I am working on a weight conversion program at the moment. I have it working correctly but now I'm trying to make it fool proof, i.e. if a user inputs a numerical value either below or over a certain range (in this case I'm looking for KG between the range of 0 and 450) a message will appear advising of the mistake and will then prompt the user to input their value again. I can do that with the following code but the problem is when the user inputs a valid value it will print the conversion of not only the valid input but also the previous incorrect value. I have attached a screenshot of Command Prompt demonstrationg the issue. Can someone please tell me where I'm going wrong? Thanks.
public void kgToStonesAndPounds()
{
double kg = 0;
System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
kg = input.nextDouble();
if ( kg >= 1 && kg <= 450 ) // validate kg
System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
else
{System.out.println( "Weight in KG must be in the range of 1 - 450" );
this.kgToStonesAndPounds();
}
double pounds = kg * 2.204622;
double stonesWithDecimal = pounds / 14;
int stone = (int) stonesWithDecimal; // cast int to get rid of the decimal
long poundsWithoutStone = (long)((stonesWithDecimal - stone) * 14); // Take the fractional remainder and multiply by 14
System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds " );
}//end method kgToStonesAndPounds
EXAMPLE IN COMMAND PROMPT
You have to add a return after you call the method again in the invalid case. That way when returning from the method call if it was called from this method it won't move out of else statement and execute the following code.
public void kgToStonesAndPounds() {
...
if ( kg >= 1 && kg <= 450 ) // validate kg
System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
else {
System.out.println( "Weight in KG must be in the range of 1 - 450");
this.kgToStonesAndPounds();
return; // here
}
...
}
Java - How to Validate Numerical User Input Within A Certain Range Correctly
As long as you get the desired effect/result (sans bad side effects), one way is no more correct than another.
Here is how I might do it. Just prompt initially and then repeat the prompt if the input isn't correct.
double kg;
String prompt = "Please enter weight in KG here, range must be between 1 and 450: ";
System.out.println(prompt);
while ((kg = input.nextDouble()) < 1 || kg > 450) {
System.out.println(prompt);
}
System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
// now do something with kg
Recursion (call a method inside itself) isn't a way to handle errors, it should only be used when the logic requires it.
To ask again, use a loop that will exits only when the input is valid
double kg;
do {
System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
kg = input.nextDouble();
if (kg >= 1 && kg <= 450) {
System.out.printf("\nThe weight you have entered is %.0f KG\n", kg);
break;
} else {
System.out.println("Weight in KG must be in the range of 1 - 450");
}
} while (true);
And you can use modulo to simplify your code
double pounds = kg * 2.204622;
int stone = (int) pounds / 14;
int poundsWithoutStone = (int) pounds % 14;
System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds ");
Both Ausgefuchster and azro' answer work, I give my answer as additional one for discuss.
I think most of your code works fine, but you should struct your code more clearly. For the if statement and else statement has no common code to execute, thus all code in the method should be seperate into different branches. Like the following:
public void kgToStonesAndPounds()
{
double kg = 0;
System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
kg = input.nextDouble();
if ( kg >= 1 && kg <= 450 ){ // validate kg
System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
double pounds = kg * 2.204622;
double stonesWithDecimal = pounds / 14;
int stone = (int) stonesWithDecimal; // cast int to get rid of the decimal
long poundsWithoutStone = (long)((stonesWithDecimal - stone) * 14); // Take the fractional remainder and multiply by 14
System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds " );
}
else
{System.out.println( "Weight in KG must be in the range of 1 - 450" );
this.kgToStonesAndPounds();
}
}//end method kgToStonesAndPounds
The reason that led to this problem is that after recursive execution of kgToStonesAndPounds completes, the code will continue to run the rest codes which follow the else block.

Declining balances issue

I am showing the declining balance of a loan per year and the interest paid per year. The first and second year are always messed up, causing the rest of the years to not be correct. Also, how do I print a column with designated space for each entry, besides using spaces to separate them like I did?
My code:
int year;
periods = loanDurationYears*12;
double annualBalance = 0;
double annualInterest = 0;
int month = loanDurationYears-(loanDurationYears-1);
balance = loanAmount;
double interestForMonth = balance*((interestRate*.01)/12);
double principalForMonth = monthlyPayment - interestForMonth;
balance = balance - principalForMonth;
System.out.println("Annual balances");
System.out.printf("%s %s %s \n","Year","Interest","Balance");
for(int j=0;j<periods;j++)
{
month++;
year = month/12;
interestForMonth = balance*((interestRate*.01)/12);
principalForMonth = monthlyPayment - interestForMonth;
balance = balance - principalForMonth;
annualBalance = annualBalance + balance;
annualInterest = annualInterest + interestForMonth;
if(month%12 == 0)
{
System.out.printf("%d %.2f %.2f \n",year,annualInterest,annualBalance);
annualBalance = 0;
annualInterest = 0;
}
}
My output:
Year Interest Balance
1 4852.43 859718.74
2 5080.12 899718.26
3 4842.34 857208.50
4 4588.01 811738.89
5 4315.96 763103.31
6 4024.98 711081.35
7 3713.73 655437.20
8 3380.81 595918.66
9 3024.71 532255.97
10 2643.82 464160.58
11 2236.40 391323.84
12 1800.62 313415.64
13 1334.49 230082.85
14 835.91 140947.76
15 302.62 45606.39
How the output should look: (besides the columns not being aligned)
Year Interest Loan Balance
1 5965.23 86408.21
2 5715.14 82566.33
3 5447.64 78456.94
4 5161.51 74061.43
5 4855.46 69359.87
6 4528.10 64330.94
7 4177.95 58951.87
8 3803.41 53198.26
9 3402.80 47044.03
10 2974.29 40461.31
11 2515.95 33420.24
12 2025.70 25888.91
13 1501.31 17833.19
14 940.40 9216.58
15 340.45 -0.00
You are getting an incorrect starting amount because you adjust the balance before the for-loop. It looks like your for-loop expects to start with the full balance, but it's already been reduced. You should also either move the increment of month to the end of the loop, or start it at zero instead of 1.
This line will always initialize month to 1. Why bother with the math?
int month = loanDurationYears-(loanDurationYears-1);
I haven't tested this or anything but it should work. I'm sure it's not the best fix but something simple like this should work fine.
It simply checks the size of the variable and then uses different print statements depending on the size of it. Also as the year throws off alignment I've put some code that should fix that
if(month%12 == 0)
{
// Set the amount of decimals for all interest rates
DecimalFormat df = new DecimalFormat("#.##");
df.format(annualInterest);
// Get the length of annualInterest
int n = math.floor(annualInterest);
int length = (int)(Math.log10(n)+1);
if (length = 3)
{
// Have 1 less space than normal on the print statement
// Maybe also do a check on the year also as that throws it out when it goes past 10
if (year > 10)
System.out.printf("%d %.2f %.2f \n",year,annualInterest,annualBalance);
else
System.out.printf("%d %.2f %.2f \n",year,annualInterest,annualBalance);
}
if (length = 2)
{
// Have 2 less spaces than normal
}
annualBalance = 0;
annualInterest = 0;
}

Unreachable code, compilation error vicious circle

So I have made a programme that calculates the cost of of a ticket based on a number of factors I'll post the question i got below
Create a program that given a number of tickets (maximum of 10),
the type of ticket (return, one way), the passenger type (under 10, under 16,
student, over 60, other), the selected route, and the starting and finishing
stops (in the form of a number where n denotes stopn ),
calculates the total cost for the journey.
The cost of each ticket should be calculated as follows:
• The cost per mile is 50p;
• Under 10 travel free when accompanied by an adult;
otherwise, a discount of 75% is applied;
• Under 16 get a 50% discount;
• Students get a 25% discount;
• Over 60’s get a 60% discount.
Train routes should be expressed in the format:
int [n] route = {stop2 , stop3 , ... stopNPlusOne};
Example:
int [4] route1 = {3, 5, 2, 6};
denotes a route with 5 stops:
the distance between stop one and two is 3 miles,
between stop two and three is 5 miles,
between stop three and four is 2,
and between stop four and five is 6.
My code is as follows
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of Tickets (Max 10): ");
int numberOfTickets = input.nextInt();
if (numberOfTickets > 10) {
System.out.println("Please choose less than 10 tickets");
} else {
double cost = route();
double totalCost = (cost * numberOfTickets);
System.out.println("");
System.out.printf("Your total cost is:", totalCost);
}
}
// DECLARE A NEW METHOD THAT CALCULATES THE DISTANCES TRAVELLED
public static double route() {
Scanner input = new Scanner(System.in);
int[] route = { 7, 12, 13, 17, 22, 26 }; // miles between each stop
System.out.println("Enter the first station number(0 - 5): ");
int firstStation = input.nextInt();
System.out.println("Enter the last station number(0 - 5): ");
int lastStation = input.nextInt();
int totalMiles = 0;
for (int i = firstStation; i < lastStation; i++) {
totalMiles = totalMiles + route[i]; // Total miles
}
System.out.println(totalMiles);
double cost = totalMiles * 0.5; // (* 0.5) because it's 50p per mile.
System.out.println("The initial cost is £" + cost);
System.out.println("Please enter your age");
int age = input.nextInt();
double totalCost = 0;
int adults = 0;
return adults;
{
{
if ((age < 10) && (age > 0)) {
cost = (cost * 0.25);
} else if ((age < 16) && (age >= 10)) {
cost = (cost * 0.5);
} else if (age > 60) {
cost = (cost * 0.4);
}
System.out.println("Are you a student, if yes enter 1 if not enter 2");
int studentPass = input.nextInt();
boolean Student = false;
if (studentPass == 1)
{
Student = true;
}
if (studentPass == 2) {
adults++;
}
return cost;
}
}
}
}
}
The issue is there is an error on the last curly bracket and so when i delete it everything from return adults and down is said to be unreachable code.
Apologies for the vast amount of text in the question. I'm in java by the way.
The problem is that you have multiple returns in the same function. When a return executes the function exits meaning that the code below will never be able to be run and thus it is unreachable.
So in this:
public int function(){
value = 0
//do stuff
return value
//do more things
}
"do more things: will never be able to be run because the function stops running as soon as return value is encountered. This code is said to be unreachable.
Put your code in multiple functions, each with only one return, and then call those functions from your main or wherever you want to use them as necessary

how to get two variables to print with one in decimal form

I am very new. apologies in advance for my coding. I need to print a table that shows year and then a tab over, and then the value with a next line. The value has to be in decimal form.
I have been reading and searching and mixing my code around. I have found it for 1 variable but not for two in same line. I have tried the printf, I have tried the good ol 100 / 100.0 and I either get errors or the decimal never goes to 2 places. I do not need it rounded, just with 2 spaces after. I am obviously going wrong somewhere. I would appreciate any assistance.
import java.util.Scanner;
public class Investment1 {
public static double futureInvestmentValue(double investmentAmount, double monthlyInterestRate, int years){
double principal = 0.0;
double futureInvestmentValue = 0;
for (years = 1; years <=30; years++){
//calculate futureInvestmentValue
futureInvestmentValue = (investmentAmount * (Math.pow (1 + monthlyInterestRate, years * 12)));
System.out.print(years + "\t" + futureInvestmentValue + "\n");
}//end for
return futureInvestmentValue;
}//end futureInvestmentValue
public static void main(String[] args){
Scanner input = new Scanner (System.in);
//obtain Investment amount
System.out.print("Enter Investment amount: ");
double investmentAmount = input.nextDouble();
//obtain monthly interest rate in percentage
System.out.print("Enter annual interest rate in percentage: ");
double annualInterestRate = input.nextDouble();
double monthlyInterestRate = (annualInterestRate / 1200);
int years = 30;
System.out.println("Years\t" + "Future Value");
System.out.print(years + "\t");
System.out.print(years + "\t" + ((int)(futureInvestmentValue(investmentAmount, monthlyInterestRate, years))) + "\n");
}//end main
}//end Investment
You can use system.out.format():
System.out.format("%d \t %.2f", years, futureInvestmentValue);
you should read about format strings, heres a simple usage example:
System.out.println(String.format("%d %.2f",myint,myfloat));
myint will be printed as an integer (even if it's a floating point value) due to the use of the %d in the format string.
myfloat will be printed as a decimal number with 2 digits after the decimal point, thanks to the %f.2 part in the format string.

calculating interest on a certificate of deposit

I'm working on a program that will calculate the basic interest accrued on a certificate of deposit. The program asks for the amount of money invested and the term (up to five years). Depending on how many years their term is, is what determines how much interest is earned. I use an if/else statement to determine the rate of interest. I then use a loop to print out how much money is in the account at the end of each year. My problem is that when I run the program, the money is not counting.
Here is the entire code.
import java.util.Scanner;
public class CDCalc
{
public static void main(String args[])
{
int Count = 0;
double Rate = 0;
double Total = 0;
Scanner userInput = new Scanner(System.in);
System.out.println("How much money do you want to invest?");
int Invest = userInput.nextInt();
System.out.println("How many years will your term be?");
int Term = userInput.nextInt();
System.out.println("Investing: " + Invest);
System.out.println(" Term: " + Term);
if (Term <= 1)
{
Rate = .3;
}
else if (Term <= 2)
{
Rate = .45;
}
else if (Term <= 3)
{
Rate = .95;
}
else if (Term <= 4)
{
Rate = 1.5;
}
else if (Term <= 5)
{
Rate = 1.8;
}
int count = 1;
while(count <= 5)
{
Total = Invest + (Invest * (Rate) / (100.0));
System.out.println("Value after year " + count + ": " + Total);
count++;
}
}
}
and here is the result I get with a 10 dollar investment, just to keep it simple, and a 5 year investment.
How much money do you want to invest?
10
How many years will your term be?
5
Investing: 10
Term: 5
Value after year 1: 10.18
Value after year 2: 10.18
Value after year 3: 10.18
Value after year 4: 10.18
Value after year 5: 10.18
My main problem is I dont know how to make it continually add the intrest onto the total. I'm not sure if I need to use a different loop or what. Any help would be appreciated.
Total = Invest + (Invest * (Rate) / (100.0));
You are not changing the value of Invest for each year, so it is not compounding. It is like you are getting .18$ of interest each year, retired from the account.
Change Total for Invest.
You need to add the investment interest to your total:
Total = Invest;
int count = 1;
while(count <= 5)
{
Total = Total + (Invest * (Rate) / (100.0));
System.out.println("Value after year " + count + ": " + Total);
count++;
}

Categories