I have the below code to run a compound interest program but I do not know why it is not working. Eclipse is giving me the error message: "The value of the local variable amount is not used."
package loops;
public class CompoundInterest {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("How much did you put into the bank?");
double deposit = IO.readDouble();
System.out.println("What is the bank's interest rate?");
double rate = IO.readDouble();
System.out.println("How many times will it compound?");
double compound = IO.readDouble();
System.out.println("How many years?");
double years = IO.readDouble();
for (int i = 1; i<=20; i++){
double amount = deposit * Math.pow(1+(rate/compound), years*compound);
}
}
}
Strictly speaking, this is a compiler warning (not an error). It's technically "legal" to have variables you don't actually use, but the compiler's telling you that it's probably a mistake. In this case, as others have indicated, you assign a value to amount but you never actually do anything with it.
As a general tip, it's helpful to pay close attention to the text of the warning - in this case, it was what it said (you don't do anything with the amount variable). Eric Lippert has an extremely helpful article available on how to debug small programs that I recommend taking a look at when you get a chance. (His explanation of "rubber-duck debugging" alone makes the article more than worth the read).
Just add a statement inside your loop to use amount as -
for (int i = 1; i<=20; i++){
double amount = deposit * Math.pow(1+(rate/compound), years*compound);
System.out.println(amount); // just a type of use
}
The warning is to notify that the amount calculated in the statement is being not in use. Once used(even for displaying as above) the warning shall go away.
Related
So I am working on an incremental game at the moment. In case you don't know what this is a short explanation. You click a button to get some kind of money (in my case gold). With enough money you can buy stuff that makes you money without even clicking. With more money you can get better upgrades which makes you even more money and so on.
Now to my problem; I created a class called Upgrade which you can see here:
public class Upgrade {
double baseCost;
double baseIncome;
int count =0;
double cost = baseCost*Math.pow(1.07,count);
double goldPerSecond = baseIncome; //TODO find usefull formula!
public Upgrade(double baseC, double baseIn){
baseCost = baseC;
baseIncome = baseIn;
}
}
The variables should explain themselves.
Now I created some Upgrades via the constructor:
Upgrade waitress = new Upgrade(50 ,2); //Constructor for Waitress
Upgrade seats = new Upgrade(100, 5); //Constructor for More-Seats
Upgrade decoration = new Upgrade(500, 20); //Constructor for Decoration
Upgrade bartender = new Upgrade (1000, 50); //Constructor for Bartender
To buy upgrades I have written the method buyUpgrade which is bound to buttons referring to the upgrades listed above.
public void buyUpgrade(Upgrade U) {
if (goldCount >= U.cost) {
goldCount = goldCount - U.cost;
clickGoldPerSecond++;
U.count++;
} else {
error.setText(getResources().getString(R.string.no_gold));
}
}
And here comes the problem. As the game starts you have 0 gold. That 0 is stored in the variable goldCount. But even though goldCount is I can buy every Upgrade in unlimited amounts. I just cant figure out the problem. Probably it is really simple and afterwards I realize how stupid I was but I just cant figure it out.
Every help is appreciated. Thank you!
The problem is that
double baseCost;
double baseIncome;
int count =0;
double cost = baseCost*Math.pow(1.07,count);
baseCost being the member variable of the class, is intialized to 0.0
SO "cost" set to 0.0 and it never changed after that.
You should move the cost calculation in the constructor.
public Upgrade(double baseC, double baseIn){
baseCost = baseC;
baseIncome = baseIn;
cost = baseCost*Math.pow(1.07,count);
}
public class Upgrade
{
double baseCost;
double baseIncome;
int count =0;
double cost ;
double goldPerSecond;
public Upgrade(double baseC, double baseIn)
{
baseCost = baseC;
cost = baseCost * Math.Pow(1.07,count);
baseIncome = baseIn;
}
}
Your Upgrade class should be similar to what I have created here. If there is a non static filed in the class and you are assigning value to that variable in the way you were doing it will not work.
In your case you also cannot use the static variable as the variable baseCost is passed as constructor parameter and will not be available until you create an instance of upgrade class.
If Condition if(goldCount >= U.cost){} Here the cost will have value of zero only as it would not get updated.
Here is your problem:
int count =0;
double cost = baseCost*Math.pow(1.07,count); // cost is set and will not be updated
Pls note that you update baseCost in your constructor, but before that the default value 0.0 is being used for baseCost * Math.pow(...);. But even if you update that, by having it done in the constructor, still you will not see any price going up, because the cost is not being recalculated at all.
Set the initial value in the constructor (or have baseCost always being added to the cost when accessing the cost).
Make a method which adds one to count and then does Math.pow(...) on cost again.
Now for a much better solution: hence, in this case the attribute cost is useless. Change it into a method:
public double getCost() {
return baseCost*Math.pow(1.07,count);
}
call it (change 2x U.cost --> U.getCost()) and your sky will be blue again, no further change needed where ever.
You are missing getter/setter for cost i guess. Therefore it always return 0.0.
I mean try to create an Upgrade object with the constructor, then print out the cost. No matter what you give in the constructor, the cost for the object always print out "0.0".
This program will calculate the amortization table for a user. The problem is my assignment requires use of subroutines. I totally forgot about that, any ideas on how to modify this to include subroutines?
public class Summ {
public static void main(String args[]){
double loanamount, monthlypay, annualinterest, monthlyinterest, loanlength; //initialize variables
Scanner stdin = new Scanner (System.in); //create scanner
System.out.println("Please enter your loan amount.");
loanamount = stdin.nextDouble(); // Stores the total loan amount to be payed off
System.out.println("Please enter your monthly payments towards the loan.");
monthlypay = stdin.nextDouble(); //Stores the amount the user pays towards the loan each month
System.out.println("Please enter your annual interest.");
annualinterest = stdin.nextDouble(); //Stores the annual interest
System.out.println("please enter the length of the loan, in months.");
loanlength = stdin.nextDouble(); //Stores the length of the loan in months
monthlyinterest = annualinterest/1200; //Calculates the monthly interest
System.out.println("Payment Number\t\tInterest\t\tPrincipal\t\tEnding Balance"); //Creates the header
double interest, principal; //initialize variables
int i;
/* for loop prints out the interest, principal, and ending
* balance for each month. Works by calculating each,
* printing out that month, then calculating the next month,
* and so on.
*/
for (i = 1; i <= loanlength; i++) {
interest = monthlyinterest * loanamount;
principal = monthlypay - interest;
loanamount = loanamount - principal;
System.out.println(i + "\t\t" + interest
+ "\t\t" + "$" + principal + "\t\t" + "$" + loanamount);
}
}
}
any ideas on how to modify this to include subroutines?
Well, you are better off doing it the other way around; i.e. working out what the methods need to be before you write the code.
What you are doing is a form or code refactoring. Here's an informal recipe for doing it.
Examine code to find a sections that perform a specific task and produces a single result. If you can think of a simple name that reflects what the task does, that it a good sign. If the task has few dependencies on the local variables where it currently "sits" that is also a good sign.
Write a method declaration with arguments to pass in the variable values, and a result type to return the result.
Copy the existing statements that do the task into the method.
Adjust the new method body so that references to local variables from the old context are replaced with references to the corresponding arguments.
Deal with the returned value.
Rewrite the original statements as a call to your new method.
Repeat.
An IDE like Eclipse can take care of much of the manual work of refactoring.
However, the real skill is in deciding the best way to separate a "lump" of code into discrete tasks; i.e. a way that will make sense to someone who has to read / understand your code. That comes with experience. And an IDE can't make those decisions for you.
(And did I say that it is easier to design / implement the methods from the start?)
I deleted my previous comment as I answered my own question by reading the associated tags :-)
As an example, define a method like this in your class:
public double CalculateInterest(double loanAmount, double interestRate) {
//do the calculation here ...
}
And then call the method by name elsewhere in your class code e.g.
double amount = CalculateInterest(5500, 4.7);
I have been trying to figure out how to make my computer develop a popup window to ask for my hourly pay, then the hours I worked and the total I will have after taxes (15%) Im not really sure what I keep doing wrong...
import javax.swing.JOptionPane;
public class payrollAdam
{
public static void main(String[] args)
{
String hourpay, hours, total,result;
double tax;
double tax = .15;
int total = result * tax;
hourpayString = JOptionPane.showMessageDialog ( "what is your hourly pay?" , "enter hour pay ", JOptionPane.INFORMATION_MESSAGE);
hoursString = JOptionPane.showMessageDialog ( "how much time worked?" , "hours spent:", JOptionPane.INFORMATION_MESSAGE);
resultString = hourpay * hours;
totalString = JOptionPane.showMessageDialog ("");
System.exit(0);
}
}
when I try to compile it states (lines 9 & 10) that the variables "tax" "total" and "income" have already been defined in method "main(String[])" The other errors on line 11: "'*' is a bad operand type for binary operator" and that my methods for showmessagedialog are not suitable (string string integer) also on line 11
Your code has a mess of errors -- you're declaring variables as Strings, then re-declaring the same variables, something not allowed.
Start over, declare your variables once and only once, and with the proper type, and it will likely work. Start by getting rid of:
String hourpay, hours, total,result;
double tax;
Also when your code has a ton of compiler errors, this tells you that your method of creating code is wrong. You should never try to add good code to bad. Always compile early and often and fix all compiler errors before trying to add new code. If you use an IDE such as Eclipse or NetBeans, you'll be flagged immediately if any compiler errors should occur.
Also in the future when asking questions about compiler errors or run time exceptions, always post those error messages with your question. They're important, they often tell you exactly what is wrong. Your lack of this key information is likely why your question was down-voted.
I'm a student starting out on my first programming module. The textbook I'm working from is 'Java for Everyone', Cay Horstmann. I'm on chapter 2.4 - Constants. I have copied and checked (over 15 times!) the code directly from the book, however every time I compile it produces the compile error in is already defined in main(java.lang.String[]).
It highlights Scanner in = new Scanner(System.in); as being the problem. I have written another extremely simple program which also includes Scanner in = new Scanner(System.in); and I had exactly the same problem.
I have tried to find the solution, I've reinstalled both Java JDK and BlueJ (compiler), but nothing has worked. I have Googled the problem, but I'm unable to find anything which matches my problem. I am a Java virgin, so to be honest it's pretty difficult to work out where I should be looking.
Any help would be greatly appreciated. I'm behind a couple of weeks already, and this is holding my progress up considerably.
Thanks, in advance, for any advice offered.
All the best,
Vicky
import java.util.Scanner;
public class Volume2
{
public static void main(String[] args)
{
final double BOTTLE_VOLUME = 2;
final double LITRES_PER_OUNCE = 0.0296;
final double CAN_VOLUME = 12 * LITRES_PER_OUNCE;
System.out.print("Please enter quantity of bottles: ");
Scanner in = new Scanner(System.in);
int bottles = in.nextInt();
double totalVolume = totalVolume * BOTTLE_VOLUME;
System.out.print("Please enter the number of cans: ");
**Scanner in = new Scanner(System.in);** // This is highlighted as being the problem
int cans = in.nextInt();
double additionalVolume = cans * CAN_VOLUME;
totalVolume = totalVolume + additionalVolume;
System.out.print("The total volume is: ");
System.out.println(totalVolume);
}
}
Error Message: in is already defined in main(java.lang.String[])
So the error message is exactly correct - you already have something named in a few lines before the line with the error. In your specific case, just remove the second declaration, since it serves no purpose.
Scanner in = new Scanner(System.in); // FIRST ONE HERE
int bottles = in.nextInt();
double totalVolume = totalVolume * BOTTLE_VOLUME;
System.out.print("Please enter the number of cans: ");
Scanner in = new Scanner(System.in); // SECOND ONE HERE
Have a look at that code segment. You are indeed trying to create two copies of in, exactly as the error message suggests.
In a normal situation where you wanted to reuse a variable, you would simply assign to it the second time, such as with:
int xyzzy = 42; // Create it here.
doSomethingWith (xyzzy);
xyzzy = 314159; // NOTE: no "int" here, simple reuse.
doSomethingWith (xyzzy);
But, in your case, this does not apply, you've simply declared the variable twice.
So, subscribing to the "create variables as late as you possibly can" philosophy, I would get rid of the first one, it's not needed. You could get rid of the second but that afore-mentioned philosophy has served me well, ensuring that creation and use of objects are localised.
The error message is pretty clear: you've already declared a variable named in inside main(). In fact, the declaration is identical, which means the second one is unnecessary. Delete the offending line, and the later code will still be able to benefit from the first declaration; everything will work fine.
You only need one Scanner to read from System.in -- once you've created one you don't need to create another; just keep reusing the one you've already made.
public class Balance {
public static void main(String[] args) {
System.out.printf("%.2f\n", balance(0.0, 0.0, 0.0));
}
/**
* #param principal
* #param rate
* #param years
* #return
*/
public static double balance(double principal, double rate, double years) {
double amount = 0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the initial investment amount: ");
principal = sc.nextDouble();
System.out.print("Enter the interest rate: ");
rate = sc.nextDouble();
System.out.print("Enter the number of years: ");
years = sc.nextDouble();
for (int i = 1; i < years; i++) {
amount = principal * Math.pow(1.0 + rate, years);
amount += principal;
}
return amount - principal;
}
}
My problem is with the printf line that I am using within the main method. Eclipse wants me to change the method balance from void to Object[]. When I do this I must return a value from balance. So I guess my question is, how would I return the proper value? Am I on the right track? Thank you for your time and constructive criticism. :)
EDIT - Thanks for the help everyone, much appreciated :) My math is off. I end up with 1000 more than I should have. hmmm.
So should I just take a 1000 from amount like so:
return amount - 1000;
Or this:
return amount - principal;
EDIT this is what I am going with since it is due tonight. Thanks to all for the assistance. :)
A few points:
balance() cannot be void, because you use its return value in S.out.printf(). Do you want balance to print to the screen, or do you want it to yield a number?
Your loop for (years = 0; years > 10; years++) won't run. Think about why. It might help to convert the for into a while, to visualize why.
You read in years as a double, but then use it as a counter in your loop. What type should it actually be?
Your balance() function takes three parameters, then immediately gets input and obliterates them. Do you want balance() to be provided these numbers, or do you want it to fetch them?
Otherwise, you seem to be on the right track.
The problem is that balance doesn't return anything, (it's a void function). Change it to:
public static double balance(double principal, double rate, double years) {
...
And inside that function, return the balance.
Java is telling you it wants an Object[] because printf is defined like this:
public static void printf(String format, Object ... params) {
// params is an Object[]
}
What this lets you do is pass parameters like this:
printf("some string", first, second, etc);
It lets you pass as many parameters as you want, and the function can handle them as if you passed an array.
It's exactly the same as if it was defined like this:
public static void printf(String format, Object[] params);
And you used it like this:
printf("some string", new Object[] { first, second, etc});
It's just easier to use.
EDIT:
The other option is to not print anything in main, but I would definitely advise returning the result and printing it in main. This follows the principle of making each function do as little as possible. balance should just calculate the balance. Printing it is unrelated.
Please consider a more drastic re-working of your code; as it is, your balance() function is doing all the work of your program (and your printf() line feels like an afterthought). If you break apart your code based on what the code does, I think you can do much better:
create a function that prompts the user and then reads in their input
create a function that calls the previous function three times for principal, rate, and years
create a function that computes and populates a payment schedule. Keep track of year, balance, payment, principal payment, and interest payment. (Or just the variables you're interested in -- but be aware that programs tend to grow new features, and these variables are often the second thing that users (or professors) ask to know when paying down a loan.)
create a function that prints the selected columns from your payment schedule.
create a function that orchestrates the previous functions.
When you re-write your program to use a GUI or webservice in three weeks, you'll definitely thank yourself for having written each function to do one task, and do it well. You'll also find it far easier to test smaller pieces of code that do only one task.
There is the risk of over engineering a too-generic solution -- what I'm really trying to suggest is a functional decomposition of your code into multiple smaller routines that do exactly what their name says. You might never move the program into a GUI or webservice or whatever, but you'll definitely be happier when someone reports that your amortization schedule is wrong, that you can control it via simpler programming, rather than having to re-type inputs all day long.
Yours is wrong, do this:
public static void main(String[] args) {
balance(1000.0, .05, 8.5);
}