Getting NaN when using get method - java

I'm making an BMI calculator for a diet programming I'm making for a piece of coursework. Originally I was making a a couple variables public static to get variables from another class. My BMI calculator worked fine this way.
I then figured out that I could use a get method (for more marks). So I changed by the previous variables to private and used a get method. But when I run this program I get NaN when the program prints out the the variable that holds the BMI, this never happened before!
Can anyone help?
import java.util.Scanner;
public class Weight {
private Scanner input;
private String readInput;
private String userWeightIsPounds;
private String userWeightIsStones;
private Scanner input2;
public static double userWeight;
public Weight(){
userWeightIsPounds = ("Pounds");
userWeightIsStones = ("Stones");
}
public void findOutUserWeightMessage(){
System.out.println("Firstly Do you weigh yourself in pounds or stones?");
}
public void findOutUserWeight(){
input = new Scanner (System.in);
readInput = input.nextLine();
if(readInput.equals(userWeightIsPounds)){
System.out.println("Ok then, enter your weight in pounds please.");
}
if(readInput.equals(userWeightIsStones)){
System.out.println("Ok enter your weight in stones please.");
}
input2 = new Scanner (System.in);
userWeight = input2.nextFloat();
if (userWeight > 20){
System.out.println("You've enetered your weight as " + userWeight + " lbs. I'll save that information for later.");
}else{
userWeight = userWeight * 14;
System.out.println("I've converted your weight into pounds for you. You weigh " + userWeight + " lbs. I'll save that information for later.");
}
}
public double static getUserWeight(){
return userWeight;
}
}
And there is come code the the class that does the calculations. Ignore some of the println's I was trying to find out what was happening with my variables.
public class BMI {
private double userHeightSqaured;
private double bmiMutiplier;
private double weightDivideHeight;
private double userBmi;
private double userWeightBmi;
private double userHeightBmi;
BMI(){
bmiMutiplier = 703;
userWeightBmi = Weight.getUserWeight();
userHeightBmi = Height.getUserHeight();
}
public void startUpBmiMessage(){
System.out.print("Lets start with your BMI then shall we? ");
}
public void calculateUserBmi(){
System.out.println("userWeightBmi is " + userWeightBmi);
System.out.println("userWeightBmi is " + userHeightSqaured);
userHeightSqaured = userHeightBmi * userHeightBmi;
System.out.println("userHeightSqaured is " + userHeightSqaured);
weightDivideHeight = userWeightBmi/userHeightSqaured;
System.out.println("weightDivideHeight is " + weightDivideHeight);
userBmi = weightDivideHeight * bmiMutiplier;
System.out.println("weightDivideHeight is " + weightDivideHeight);
System.out.println("bmiMutiplier is " + bmiMutiplier);
}
public void calculateUserBmiMessage(){
System.out.println("Your bmi is " + userBmi);
}
}

It sounds like you're trying to write a Java program that performs some calculations, and the result of your calculation is NaN - you can refer to the question In Java, what does NaN mean? for some info on NaN.
As for resolving your problem without seeing any code, and assuming your calculation worked fine with the same input before, it sounds like your switch from public static variables to private ones with getters has probably left some of your variables uninitialized, so their value defaults to 0 - Division by 0 is a common cause of NaN.

The reason for the NaN is that this statement:
weightDivideHeight = userWeightBmi/userHeightSqaured;
divided zero by zero. In other words userWeightBmi and userHeightSqaured were both zero at that point.
The root problem seems to be that you haven't got your head around the difference between static and instance variables. And when you should / should not use the two kinds of variable.

Related

Using method to call for a y/n answer

I have this code. The askToContinue() method is being called to ask the user if they would like to continue but my problem is it just ignores the choice and starts the program again no matter what I enter. What am I missing in the code that is causing it to ignore my choice?
public class FutureValueApp {
public static void main(String[] args) {
System.out.println("Welcome to the Future Value Calculator\n");
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y")) {
// get the input from the user
System.out.println("DATA ENTRY");
double monthlyInvestment = getDoubleWithinRange(sc,
"Enter monthly investment: ", 0, 1000);
double interestRate = getDoubleWithinRange(sc,
"Enter yearly interest rate: ", 0, 30);
int years = getIntWithinRange(sc,
"Enter number of years: ", 0, 100);
System.out.println();
// calculate the future value
double monthlyInterestRate = interestRate / 12 / 100;
int months = years * 12;
double futureValue = calculateFutureValue(
monthlyInvestment, monthlyInterestRate, months);
// print the results
System.out.println("FORMATTED RESULTS");
printFormattedResults(monthlyInvestment,
interestRate, years, futureValue);
System.out.println();
askToContinue(sc);
}
}
private static void printFormattedResults(double monthlyInvestment,
double interestRate, int years, double futureValue){
// get the currency and percent formatters
NumberFormat c = NumberFormat.getCurrencyInstance();
NumberFormat p = NumberFormat.getPercentInstance();
p.setMinimumFractionDigits(1);
// format the result as a single string
String results
= "Monthly investment: " + c.format(monthlyInvestment) + "\n"
+ "Yearly interest rate: " + p.format(interestRate / 100) + "\n"
+ "Number of years: " + years + "\n"
+ "Future value: " + c.format(futureValue) + "\n";
System.out.println(results);
}
public static String askToContinue(Scanner sc){
// see if the user wants to conti1nue
System.out.print("Continue? (y/n): ");
String choice = sc.next();
System.out.println();
return choice;
}
You're on the right track. Change this
askToContinue(sc);
to
choice = askToContinue(sc);
Because you need to assign the value returned from askToContinue to the local reference named choice.
You are not assigning the result of askToContinue to the choice variable which is checked in the loop.
Possibly the confusion is the choice variable inside the askToContinue method. Note, this is a different variable and does not affect the choice variable checked in the while statement.
When you define a variable inside a method, it is not recognized by the code outside of your method, even if it has the same name. So, in your code for example, you have,
public static String askToContinue(Scanner sc){
// see if the user wants to conti1nue
System.out.print("Continue? (y/n): ");
String choice = sc.next(); // this choice variable exists only for the
// askToContinue method
// Once you assign it over here and return it
// with the code below, you should use the returned
// value to update the variable choice, which is
// defined outside your askToContinue method
System.out.println();
return choice;
}
So, as the other answers have pointed out, if you do,
choice = askToContinue(sc);
then the code will run fine since the choice variable defined in the main method will get updated according to the value you input
Based on
John Camerin's answer,to skip double assigning in your code, you can make your choice variable as global static variable by define it in your class :
public class FutureValueApp {
public static String choice;
}
Or send it as second parameter in your method :
askToContinue(sc,choice);

Java Basic Object Oriented Gratuity Calculator

I'm beginning to learn more about Java and I'm trying to code a Gratuity calculator that takes user Input, and shows how much a tip would be at %10 and %20 of the total. I'm getting a single "Cannot make a static reference to the non-static method" error that I can't resolve.
Gratuity class:
public class Gratuity{
//variables
private double total = 0;
private double grat1 = 0;
private double grat2 = 0;
public Gratuity(float value){
total = value;
}
start getters and setters
public double getTotal() {
return total;
}
//method to do the calculations
public void calcGrat(){
grat1 = total * .10;
grat2 = total * .20;
}
public double getGrat1(){
return grat1;
}
}
And the class with the main method:
import java.util.InputMismatchException;
import java.util.Scanner; //import package to use the scanner input function
//TestGrat main class contains method
public class TestGrat {
Scanner keyboard = new Scanner(System.in);
//method to prompt user for total, double is total
public void askForInput(){
try{
System.out.println("Enter the total amount of your bill");
total = keyboard.nextDouble();
}
catch(InputMismatchException e){
System.err.printf("Error, please try again. Program will now close");
System.exit(0);
}
}
public Scanner getKeyboard() {
return keyboard;
}
public void setKeyboard(Scanner keyboard) {
this.keyboard = keyboard;
}
//main method
public static void main(String[] args){
// asks for input in float form
float value = askForInput();
//Creating the gratCalc object and storing value as a float (total)
Gratuity gratCalc = new Gratuity(value);
// get the total value and set as float
float tot = (float)gratCalc.getTotal();
// converting the float value into string
System.out.println("You have entered: " + Float.toString(tot));
gratCalc.calcGrat(); //sets grat
// Displaying the options to user
System.out.println("Below are the tips for %10 as well as %20 ");
//getting the value and then displaying to user with toString
float getNum = (float) gratCalc.getGrat1();
float getNum1 = (float) gratCalc.getGrat2();
// using the value of getNum as float to put into toString
System.out.println( "For %10: " + Float.toString(getNum));
System.out.println(" For %20: " + Float.toString(getNum1));
}
}
Any help would be appreciated. Thanks!
askForInput() is inside your class TestGrat. However, in main() you are calling it directly, as if it was static. You probably meant:
TestGrat test = new TestGrat();
float value = test.askForInput();
askForInput() is also returning void, so you probably want to fix that too.

My variables are not initializing properly

In my code below double getAirSpeed double calcPatternwidth and double calcPatternLength are not being initialized properly, why?
/**
* holding patterns
* assignment 1
* question 2
**/
import java.util.Scanner;
public class StockiColeA1Q2 {
public static void main(String []args) {
Scanner keyboard = new Scanner(System.in);
double getAirSpeed ;
double calcPatternWidth;
double calcPatternLength;
System.out.println("That speed is " + getAirSpeed +
"\nHolding pattern width: " + calcPatternWidth +
"kms\nHolding pattern length: " + calcPatternLength + "kms");
}//main
public static double getAirSpeed() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the speed in Knots: ");
double knots = keyboard.nextDouble(); //knots given by user
return knots*1.852;
}//get air speed
public static double calcPatternWidth(double knots) {
return (knots/60*Math.PI)*2;
}//patern width
public static double calcPatternLength(double knots) {
return knots/60 + (knots/60*Math.PI)*2;
}//pattern width
}//class
You aren't properly initializing the variables in main. You show call the functions and assign them up front and then display them. I think what you were looking for was a main that looked liked this:
public static void main(String[] args) {
double getAirSpeed = getAirSpeed();
double calcPatternWidth = calcPatternWidth(getAirSpeed);
double calcPatternLength = calcPatternLength(getAirSpeed);
System.out.println("That speed is " + getAirSpeed + "\nHolding pattern width: " + calcPatternWidth
+ "kms\nHolding pattern length: " + calcPatternLength + "kms");
}// main
The code above uses the getAirSpeed as a parameter to calcPatternWidth and calcPatternLength. I am guessing that was what you intended to accomplish.
You really should close the Scanner object when finished so I'd amend getAirSpeed() to call keyboard.close() before returning.
public static double getAirSpeed() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the speed in Knots: ");
double knots = keyboard.nextDouble(); // knots given by user
keyboard.close();
return knots * 1.852;
}// get air speed
Here I am not able to see where you are initializing the given variables. As all three vairables are local to main method so compiler will not assign the default value to them. just creating getter of those variable will not assign the value. If you create the variable out side the main method in class the compiler will assign the defaut value but you have to make them static as main method is static and you cannot use non-static variable inside the static block.

Output error resulting from logic error when determining percentage based on incremental while loop

I have created a simple class which calculates the win/loss percentage and returns the amount of necessary consecutive wins to obtain the desired win/loss percentage of the given input from the user, based on the given values of wins, loss, and desired win/loss. However, whilst running the program, I notice the output gives an exceedingly large number in the place of what should be a relatively small number (the number of wins needed). I am not certain what error I have made that created this, but I'm certain it's relative to the while loop located in my howManyToWinLoss() method, or perhaps some error I've made in the tester class's output. At any rate, they are both located below, and I appreciate the assistance:
public class WinLossCalculator
{
private int win;
private int loss;
private int totalGames;
private double desiredWinLoss;
private double winLoss;
private int gamesToDWL;
public WinLossCalculator(int w, int l, double dwl)
{
win = w;
loss = l;
totalGames = w + l;
desiredWinLoss = dwl;
}
public double winPercent()
{
return winLoss = (double)win/(double)totalGames;
}
public double lossPercent()
{
return (double)loss/(double)totalGames;
}
public int howManyToWinloss()
{
int x = 0;
while(winLoss < desiredWinLoss)
{
winLoss = (win+x)/(win+x+loss);
if(winLoss < desiredWinLoss)
{
x++;
}
}
return gamesToDWL = x;
}
}
and
import java.util.*;
public class WinLossTester
{
public static void main(String []args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter the amount of matches you've won: ");
int wins = in.nextInt();
System.out.print("\nEnter the amount of matches you've lost: ");
int losses = in.nextInt();
System.out.print("\nEnter your desired match win percentage (eg. 75.4): ");
double desiredWLP = in.nextDouble();
System.out.println();
WinLossCalculator one = new WinLossCalculator(wins, losses, (desiredWLP / 100));
one.winPercent();
one.howManyToWinloss();
System.out.printf("Win percentage: %6.1f", (one.winPercent()*100));
System.out.print("%");
System.out.printf("\nLoss percentage: %5.1f", (one.lossPercent()*100));
System.out.print("%");
System.out.println("\nVictories required to reach desired W/L percent (without loss): " + one.howManyToWinloss());
}
}
Additionally--I feel as though my tester class's output section is a little ugly, might anyone have any suggestions concerning formatting or cleaning up the code in the output section?
Ok, apparently it has to do with me not casting the first line in my for loop to double like this winLoss = (double)(win+x)/(double)(win+x+loss); I don't know why that broke it, but, that's why it was broken.

Re-assigning the value to a double in a for loop

I'm currently working on a program that will calculate a simple interest rate and monthly payment taken from a loan. Although, I am running into one pretty big problem. I am trying to make it so that my principal value(see in code) is re-assigned the value of my new balance(see in code). Here is my code right now, I will explain in better detail under it:
import java.util.Scanner;
public class Payments {
public static double principal; //principal
public static double annualrate; //annual interest rate
public static double p; //monthly payment
public static double mr; //monthly interest rate
public static double nb; //new balance after monthly payments
public static double i; //interest (monthly)
public static String spaces = " "; //spaces for making clean columns
public static int months = 12;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("Principal: $");
principal = input.nextDouble();
System.out.println("Anual Interest Rate: ");
annualrate = input.nextDouble();
System.out.println("Monthly Payment: $");
p = input.nextDouble();
calculate();
}
public static void calculate() {
mr = annualrate / 12;
i = mr * p;
nb = principal + i - p;
System.out.print("Month Principal Amt. Interest Payment New Balance");
System.out.println();
System.out.println();
for(int x = 1; nb > 0; nb = principal + i - p){
System.out.println(x + spaces + p + spaces + i + "%" + spaces + "$" + p + spaces + "$" + nb);
p = (Double)null;
p = nb;
}
}
}
So as you can most likely see by the comments in the code, all of the variables are shown. Now, disregard the null and me casting it to a double because that was the last thing that I tried to do before asking you guys :) anyways, my final question is, how can I go about re-assigning the value of principal to my new balance (nb)? Also, a side question, would a while-loop be better for this kind of program?
This has already been said in the comments, but the most immediate problem that I can see is in
for(int x = 1; nb > 0; x++){
your condition, nb > 0 will never ever change in that loop.
This means 1 of 2 things
your loop won't execute
your loop won't exit (infinite loop)
judging by how you're calculating nb(new balance) I'm assuming that it's going to be above 0 most of the time, and that your loop will never stop.
As things are right now, I'm not entirely sure what you actually want to do in that for loop or whether you even want a for loop at all, as that part is unclear.
what is the for loop supposed to do?
it almost looks like you're attempting to do something like
for (int x = 1; principal > 0; x++)
{
principal += principal * monthlyInterestRate;
principal -= payment;
System.out.println("insert output here");
}
nb = p + i - p; ???? looks like you need to double check your code.. the for loop doesnot change the condition at any place.. if the value is greater than 0, you will always lead it to an infinite loop, or it will never enter the loop at all( if np<1) . so check you code for runtime errors..

Categories