How to get my rate values to display correctly? - java

I finally got my program to compile without any errors and the first half is correct the total pay, retirement deduction and net pay were all displaying 0. I saw from a different post that Java doesn't analyze the logic of your if blocks so I edited my code to have my rate assigned to 0 and my if statement to return rate. I'm now getting the error "unexpected return value". How do I get my program to have the appropriate value depending on the user's input?
import java.util.*;
public class AcmePay {
public static void main(String[] args) throws Exception {
Scanner keyboard = new Scanner(System.in);
double hours;
int shift;
int plan;
double rate = 0;
double overtimePay;
double paycheck;
//double retirement;
// double retirement = paycheck - (paycheck * .03);
//double netPay = paycheck - retirement;
System.out.println("How many hours did you work this week?");
hours = keyboard.nextDouble();
if ( hours <= 40 )
{
paycheck = hours * rate;
}
else
{
paycheck = (40 * rate) + ((hours - 40)) * (rate*1.5);
}
System.out.println("What shift did you work? 1, 2, or 3?");
shift = keyboard.nextInt();
if (shift == 1)
{
rate = 17;
return rate;
}
else if (shift == 2)
{
rate = 18.50;
return rate;
}
else if (shift == 3)
{
rate = 22;
return rate;
}

To print the rate, the last part of your code can be like this:
shift = keyboard.nextInt();
if (shift == 1) {
rate = 17;
} else if (shift == 2) {
rate = 18.50;
} else if (shift == 3) {
rate = 22;
}
System.out.println("Rate = " + rate);
i.e. remove the return statements and then print the rate at the end. You can't return a value from a void method like main(), hence the error.
If you want to calculate the rate using a separate method, you would do something like this:
private static double rateForShift(int shift) {
if (shift == 1) {
return 17;
} else if (shift == 2) {
return 18.50;
} else if (shift == 3) {
return 22;
}
return 0;
}
This method returns a double, so now you can (and have to) use return statements.
You would call it from the main method with:
double rate = rateForShift(shift);
It's a good idea to split your code into focused methods, like this, because it makes it easier to read and work with.
I think your code has a "logic" bug in it because you are using the rate variable to calclulate paycheck, but the rate variable is always 0 at the point you use it. You should probably ask both questions before you calculate the paycheck amount.
A full program would look like this:
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("How many hours did you work this week?");
double hours = keyboard.nextDouble();
System.out.println("What shift did you work? 1, 2, or 3?");
int shift = keyboard.nextInt();
double paycheck = calculatePayCheck(rateForShift(shift), hours);
System.out.println("Paycheck = $" + paycheck);
}
private static double calculatePayCheck(double rate, double hours) {
if (hours <= 40) {
return hours * rate;
} else {
return (40 * rate) + ((hours - 40) * (rate * 1.5));
}
}
private static double rateForShift(int shift) {
if (shift == 1) {
return 17;
} else if (shift == 2) {
return 18.50;
} else if (shift == 3) {
return 22;
}
return 0;
}
In Java programs you don't need to declare your variables at the top. The convention is to declare them as you need them.
Example
How many hours did you work this week?
20
What shift did you work? 1, 2, or 3?
2
Paycheck = $370.0
It's also worth mentioning that, although fine for a toy example, in a real system you should not use floating point numbers (like double) to represent money.

ELEVATE covered the code, so I'll cover the theory.
In Java (and in many other programming languages), a method is a block of code that may or may not take in an input and may or may not give an output. Whether or not the method gives an output can be determined by analyzing the method definition. If a primitive type (for example, int or double) or Object (for example, Scanner) is used in the method definition, then that method will return that type as output. If the keyword void is used in the method definition, then that method will return no output.
A key point to understand is this: Once a method is told to return a value, that method will terminate. Thus, you cannot include any code after a return statement, or your compiler will be angry with you and yell at you for including "unreachable code."
Now, to apply this to the specifics. The main method in Java uses the keyword void to indicate that it will not return any sort of output. Thus, return rate; is inappropriate for two reasons:
Returning a double value is indeed some sort of output, which contradicts the method definition of main in which main was set to return no output by the keyword void.
return rate; will cause your program to terminate immediately. Assuming that ELEVATE was correct about how you should reorder your code, leaving a return statement in your answer would cause you further problems by preventing your code from moving on to calculate your paycheck.
Side Note: A method that returns no output can still use the return keyword, but it cannot be used with any sort of value or object. For example, the following method is valid because return isn't paired with any sort of value.
public class ReturnExample {
/*Other stuff.*/
public void returnNothing() {
System.out.println("Now returning nothing.");
return;
}
}
}

Related

Java square root calculator?

Ok, I'm a beginner in java, learning on my own through websites and books. I tried a simple square root calculator with a for loop and a while loop (I've included what I tried below). Sadly, all my code does when I enter a number is terminate. Any help would be appreciated!
import java.util.Scanner;
public class The2RootProdject {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
double rootIt = input.nextDouble();
double dummy = 0.0000000;
while (dummy != dummy * dummy) {
dummy += 0.0000001;
if (rootIt == dummy * dummy) {
System.out.println("the squar root of " + rootIt + " is "
+ (dummy * dummy));
}
}
}
}
You have a couple of problems here:
1) Logical bug: 0 == 0 * 0
<= This means while (dummy != dummy * dummy) {..} will never be untrue, and you'll never even enter the loop
2) Floating point numbers are inexact, so your algorithm (which relies on "==") might not work anyway
Look here for more details on floating point imprecision:
http://www.lahey.com/float.htm
This is true for ANY language - your algorithm for square root must take this into account.
Try to use this algorithm which use Newton's iteration:
import java.util.Scanner;
public class Main
{
public static void main(String args[])
{
double number, t, squareRoot;
Scanner input = new Scanner(System.in);
number = input.nextDouble();
squareRoot = number / 2;
do
{
t = squareRoot;
squareRoot = (t + (number / t)) / 2;
}
while ((t - squareRoot) != 0);
System.out.println(squareRoot);
}
}
Newton's iteration is an algorithm for computing the square root of a number via the recurrence equation:
X(n+1) = (X(n) + number/X(n))/2
I think the while condition is supposed to be =
while(rootIt != dummy * dummy) {}
Your current condition will only ever be true if you initialized dummy as 1; but I don't that would be what you want anyways.

Using a recursive method instead of a while loop

I'm working on a project for a Java 2 class which has to show population growth of organisms for a period of days inputted by the user. I was able to implement the method using a while loop, but am having difficulty converting it to a recursive method.
while(day <= totalDays)
{
if (day == 1){
System.out.println(organs);
day++; //day one there is no increase
}
else{
organs = organs + organs*(increase/100); //add % increase of organisms
System.out.println(organs);
day++;}
}
Here is my unsuccessful attempt at a recursive method so far.
public static double showPopulation(int dayNum, int days, double organisms,
double dailyIncrease)
{
if(dayNum == totalDays)
{
return organisms + (organisms*dailyIncrease);
}
else
return showPopulation(dayNum+1, days, organisms, dailyIncrease) + organisms*dailyIncrease;
public int population(int days, int startingOrganisms, double dailyIncrease) {
if (days <= 1) {
System.out.print(days + " " + startingOrganisms);
//no increase, finish condition
return startingOrganisms;
} else {
// we need to find the population of yesterday to know how much organisms exist today
int populationYesterday = population(days - 1, startingOrganisms, dailyIncrease);
int populationToday = populationYesterday + (populationYesterday * dailyIncrease / 100);
System.out.print(days + " " + populationToday);
return populationToday;
}
}
And then just invoke it and print the result
System.out.println( population(10, 1000, 30.2);
Do you need to print the growth each each step of the way?
While I guess thisis for Homework, here is how it should work
public static double showPopulation(int dayNum, double organisms,
double dailyIncrease)
{
if(dayNum == 1)
{
return organisms + (organisms*dailyIncrease);
}else{
return showPopulation(dayNum-1, organisms, dailyIncrease) + organisms*dailyIncrease;
}
}
I did not run it, so beware of further bugs.
You forgot the termination condition. It must always get a step closer to this condition, usually by decreasing until reaching 0 or similar.
try this code:
public static double showPopulation(int totalDay,int days, double organisms,
double dailyIncrease) {
if(days == totalDay) {
return organisms;
}
else{
organisms+=organisms*dailyIncrease;
return showPopulation(totalDay,++days, organisms, dailyIncrease);
}
}
Call the following function by showPopulation(totalDays, organ, dailyIncrease). Here I am assuming totalDays is the entire number of days, organ is the initial value of the "organs", and dailyIncrease is a percentage.
public static double showPopulation(int dayNum, double organ, double dailyIncrease) {
if(dayNum <= 1) {
return organ;
} else {
return (1 + dailyIncrease) * showPopulation(dayNum - 1, organ, dailyIncrease);
}
}
Generally, when using iteration we usually start from the base case. In terms of this question, it means day 1, or when dayNum == 1. Whereas when applying recursion, we usually start considering the problem from the final state of the procedures. In this problem, it means the last day (totalDays).

Answer returning 0

Total beginner in Java. My result keeps turning up as 0 where I want it to turn up as membercount * members (ie if there are 100 members and the weather = 1, the total should be 25). I can't seem to figure out where I'm going wrong. I figure I'm not properly having my program store the information entered by the user so the doubles keep reading as 0. Here is my code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package playgolf;
import java.util.Scanner;
import javax.swing.JOptionPane;
/**
* #author Alex
*/
public class PlayGolf {
public static void main(String[] args) {
golf stats = new golf();
stats.getData();
golf total = new golf();
total.display_data();
}
}
class golf {
private double members;
private double weather;
private double temp;
private double membercount;
public double total;
public void getData() {
Scanner input = new Scanner(System.in);
System.out.print("How many members are there?: ");
members = input.nextInt();
System.out.print("What is the weather like? (Enter 1 for sunny, 2 for overcast, 3 for rain): ");
weather = input.nextInt();
System.out.print("What is the temperature? (in Farenheight): ");
temp = input.nextInt();
if (weather == 1) {
membercount = .25;
if (weather == 2) {
membercount = .12;
if (weather == 3) {
membercount = .03;
}
}
}
if (temp < 32) {
membercount = 0;
System.out.println("No one will play today, it's too darn cold!");
}
total = (membercount * members);
}
public void display_data() {
System.out.println(" ");
System.out.println("This many members will play today: ");
System.out.println(total);
}
}
You create new object again, it should be:
public static void main(String[] args) {
golf stats = new golf();
stats.getData();
stats.display_data();
}
Bug 1
The code blocks related to your weather logic are messed up; the closing braces are in the wrong place.
Properly indented, your code looks like this:
if (weather == 1) {
membercount = .25;
if (weather == 2) {
membercount = .12;
if (weather == 3) {
membercount = .03;
}
}
}
Now you can probably already see the bug. If weather is 2, the weather == 2 condition will never be reached (weather cannot be 1 and 2 at the same time).
Corrected version:
if (weather == 1) {
membercount = .25;
}
else if (weather == 2) {
membercount = .12;
}
else if (weather == 3) {
membercount = .03;
}
Bug 2
Another bug is in the main method. You should call display_data() on the same object as getData(). This would work:
golf stats = new golf();
stats.getData();
stats.display_data();
Other problems & style issues
display_data is not idiomatic Java method name. Should be displayData.
Likewise, Java class names should start with uppercase letter. Golf, not golf. See e.g. this guide on Java naming conventions.
It's suspicious to use double to represent one of three possible values (weather). Use int, or better yet, an enum. Also for members it is a pretty odd choice of type.
Since your if conditions are nested, if weather != 1, the checks for weather == 2 and weather == 3 are never reached.
As a consequence, membercount is never set and takes the value of zero, yielding your zero result for total.
You should just have something like the following:
switch (weather) {
case 1:
membercount = .25;
break;
case 2:
membercount = .12;
break;
case 3:
membercount = .03;
break;
default:
// Do nothing or, better yet, produce an error
}
if (temp < 32) {
// ...
You could simply use a series of ifs, or an if-else chain. I'm using a switch because it's the safest choice in this case. This assumes that you change weather to be an int, which is actually preferable given your use of the variable. You should also esplicitly initialize the value of weather during declaration (or in the constructor, as you see fit):
private int weather = 0;
As pointed out by the other answers, you have a secondary bug in your listing: you should create only one object and have both calls on that, as follows:
golf stats = new golf();
stats.getData();
stats.display_data();
You are calling getData() on one instance (of golf) and calling display_data() on another one. The stats collects data, but the total does not. Try to call display_data() on stats instance / or call getData() on total instance / or use shared members (statics I mean).
golf stats = new golf();
stats.getData();
stats.display_data();
or
golf total = new golf();
total.getData();
total.display_data();

How to call up calculations in custom methods to main Method

I have a main method and 4 other function type methods which include calculations, however, How would I call each one up into the main and proceed to print out the calculations. Also I am currently getting a lot of syntax errors.
I've tried placing brackets and braces when needed, however, that has just resulted into more errors. Also, I tried initializing Strings and integers elsewhere, which still seems to fail to work. Any help would be much appreciated!
Some syntax errors include: ';' expected on line 60
insert ';' to complete localVariableDelcartion on line 60
these errors are repeated for every line
import java.io.*;
//create the class
public class CirclemethodsFixedagain
{
//main method
public static void main(String[] args) throws IOException
{
BufferedReader myInput = new BufferedReader(new InputStreamReader(System.in));
String numInput;
String reqInput;
String amountStr;
double numInt = 0;
double num = 0;
System.out.println("This program will ask for a given user radius, then proceed to calculate the user input");
System.out.println("The program will use four methods to achieve this, all calling back to the main method");
System.out.println("Press any key to continue");
numInput = myInput.readLine();
// more user questions
System.out.println("First, what would you like to calculate?");
System.out.println("Enter '1' for Circumference, '2' for area, '3' for volume, or '4' for surface area");
System.out.println("*NOTE* Pressing a key outside of this range or a regular character will re-prompt the original message");
reqInput = myInput.readLine();
numInt = Double.parseDouble(reqInput);
// more user questions
System.out.println("Now enter the radius of the required shape(Half of diameter)");
System.out.println("*NOTE* Pressing a regular character will re-prompt the original message");
numInput = myInput.readLine();
num = Double.parseDouble(numInput);
}
//user created method, with each
public static int circlemethods(double circumference) throws IOException {
{
if (numInt == 1)
{
System.out.println("You chose to calculate circumference, given the radius :" + num);
circumference = (Math.PI) * (2) * (num);
System.out.print("The circumference of that sphere is :");
return circumference;
}
public static double circlemethods2 (double area) throws IOException
{
if (numInt == 2)
{
System.out.println("You chose to calculate area, given the radius :" + num);
area = (Math.PI * num * num);
System.out.print("The area of the circle is :");
return area;
}
}
public static double circlemethods3 (double volume) throws IOException
{
if (numInput == 3)
{
System.out.println("You chose to calculate volume, given the radius :" + num);
volume = (4 * Math.PI * num * num * num) / 3 ;
System.out.print("The volume of that sphere is : cm³");
return volume;
}
}
public static double circlemethods4 (double surfaceArea) throws IOException
if (numInput == 4)
{
System.out.println("You chose to calculate surface area, given the radius :" + num);
surfaceArea = 4 * Math.PI * num * num;
System.out.print("The Surface area of that sphere is :");
return surfaceArea;
}
}
}
}
Your braces - the { and } characters - don't match up. I have fixed the indentation of the code in the question so that you can better see where the problem gets started - in the method circlemethods. Also, circlemethods4 is missing its braces.
Keeping consistent indentation levels throughout the program makes these kinds of errors a lot more obvious to spot.
Compilation errors are caused by:
You can not place methods inside other method, move circlemethods 2,3,4 outside the circlemethod1.
Your circlemethods don't see numInt local variable. It is declared in main method and it is visible only in that one.
I believe you don't need if statements at the begining of each circlemethods. You rather need something like that:
if (numInt == 1)
{
circlemethod1(radius);
} else if (numInt == 2) {
circlemethod2(radius);
}
etc. in your main method.
You can also change argument's name of each circlemethod, as I understood it is always radius. Current name of arguments is a good candidate for method name.
Following are the inputs that will fix the problem :
You can't declare method inside a method, It's not JAVA syntax. Just check the bracing correctly. Use any IDE for doing the same.
Make numInt, num as static (Class) variables. As you are using those in static method.
Use proper names and camelCasing nomenclature to name any method.
|e.g calculateCircleArea(), calculateCircleVolume(), etc..
Hope this solves your problem.

JAVA: Runtime Exception (I think that's what i need to use)

Ok, I need my program to validate user entered data. If that data is invalid, the program needs to skip almost all of my code and get to the end of my while loop to ask if the user would like to proceed with calculating another loan. My professor has not provided us with a method of doing this and all the information ive found on the internet is not specific enough to help me. Once again, I need the code after the validation to be skipped without exiting the program and go to the end of the loop where I ask the user if they want to calculate another loan. Here is my code thus far.
/* This program is an extension of the previous Interest Calculator. The only different is this one can
compute not only simple interest but daily and monthly compound interest using a switch statement to
differentiate each type of interest. */
import javax.swing.*;
// Import the GUI methods
public class InterestCalculatorLoop {
public static void main(String[] args) {
// Entry point of program
String again = "yes";
while (again.equalsIgnoreCase("yes" ))
{
String option = JOptionPane.showInputDialog("Which type of loan would you like to find interest for? \n1 = Simple Interest \n2 = Monthly Compounded Interest \n3 = Daily Compounded Interest");
int optionInt = Integer.parseInt(option);
int interestType = Integer.parseInt(option);
String paString = JOptionPane.showInputDialog("Enter the principal amount");
double pa = Double.parseDouble(paString);
double interest = 0;
double months = 0;
double totalInterest = 0;
double years = 0;
final double daysInYear = 365.0;
final double daysInMonth = 30.41666666667;
final double monthsInYear = 12.0;
// Logic statements to validate user input or otherwise run through the rest of the program without calculation
if (pa <= 0)
{
JOptionPane.showMessageDialog(null, "Data Error: The principal amount must be greater than zero. You entered " + pa);
return;
}
else
{
String interestString = JOptionPane.showInputDialog("Enter The Annual Interest Rate [1 - 100 percent]) ");
interest = Double.parseDouble(interestString);
}
if (interest < 0 || interest > 100)
{
JOptionPane.showMessageDialog(null, "Data Error: The interest amount must be between 1 and 100. You entered " + interest);
return;
}
else
{
String monthsString = JOptionPane.showInputDialog("Enter the number of months");
months = Double.parseDouble(monthsString);
}
if (months <= 0)
{
JOptionPane.showMessageDialog(null, "Data Error: The number of months must be above 0. You entered " + months);
return;
}
else
{
switch (optionInt)
{
// Case for simple intrest
case 1: optionInt = 1;
months = months/monthsInYear;
totalInterest = pa * (interest/100.0) * months;
JOptionPane.showMessageDialog(null, "The total amount of interest of your loan is $" + totalInterest + ".");
break;
// Case for monthly compounded interest
case 2: optionInt = 2;
interest = interest/100.0;
years = months/monthsInYear;
double exponent = months*years;
double interestOverMonths = 1+interest/months;
double thirdTotal = Math.pow(interestOverMonths, exponent);
double secondTotal = pa*thirdTotal;
totalInterest = secondTotal - pa;
JOptionPane.showMessageDialog(null, "The total amount of interest of your loan is $" + totalInterest + ".");
break;
// Case for daily compounded interest
case 3: optionInt = 3;
interest = interest/100.0;
double days = months*daysInMonth;
years = days/daysInYear;
exponent = days*years;
double interestOverDays = 1+interest/days;
thirdTotal = Math.pow(interestOverDays, exponent);
secondTotal = pa*thirdTotal;
totalInterest = secondTotal - pa;
JOptionPane.showMessageDialog(null, "The total amount of interest of your loan is $" + totalInterest + ".");
break;
}
}
again = JOptionPane.showInputDialog("Would you like to compute another loan? (yes or no)");
}
}
}
Break is very useful for stopping loops as you said you wanted. Essentially it has the effect of setting the boolean parameter of a for loop to true.
You can of course, use what in CMD is referred to a GOTO. you can create something like:
top:
for(int i = 0; i < 10; i++){
if(i == 9){
break top;
}
}
I've skimmed through your code and to be honest, I don't know much about loans and the calculations associated with it.
As you're clearly still learning the basics, a simple solution by the looks of it would be to take out:
while (again.equalsIgnoreCase("yes" ))
{
/*
* FROM HERE
*/
String option = JOptionPane.showInputDialog("Which type of loan would you like to find interest for? \n1 = Simple Interest \n2 = Monthly Compounded Interest \n3 = Daily Compounded Interest");
int optionInt = Integer.parseInt(option);
//...
/*
* TO HERE
*/
again = JOptionPane.showInputDialog("Would you like to compute another loan? (yes or no)");
}
And put it in its own method called for example:
public static void askAndProcessDetails()
So when you return you will go to the repeat dialogue.
while (again.equalsIgnoreCase("yes" ))
{
askAndProcessDetails();
again = JOptionPane.showInputDialog("Would you like to compute another loan? (yes or no)");
}
continue is maybe one of the worse feature of java, with the break keyword (except in switch statements). It leads to jigsaw code where you have to find out where the code jumps. One continue may be practical but it gets very hard to change the code it produces (think about adding an inner loop..), and 2 continues will make you crazy.
You can always avoid using continue, there is always another solution. Same for break.
Here, why don't you just use some kind of
if( answerIsValid ) {
//process it
...
}//if
That's easy, simple, clear and even better when you have a separate method that contains processing.
Also, in your case, that is tied to robustness, you could provide a process() method that throws an exception if the data entered is not valid. This makes it even more clear that there is a "normal" program behavior and a bunch of strange cases you handle as errors.
public void processAnswer( String stringAnswer ) throws ArithmeticException {
int answer = Integer.parseInt( stringAnswer );
//rest of processing
...
}//met
then your main loop becomes
String again = "yes";
while (again.equalsIgnoreCase("yes" ))
{
String stringAnswer = JOptionPane...
try {
process( stringAnswer );
} catch( ArithmeticException ex ) {
JOptionPane.showMessageDialog( "This is not an integer !" );
}//catch
}//while

Categories

Resources