Can anyone help me here?? I have compiled and successfully run a program using Java which takes user inputs from an "inputdialog" box and displays this information back in the console along with a simple mathematical formula. The problem I cannot seem to overcome is when the data is input the user has an option to enter another set of the same data type but I need the console to register this as a second input. This is how far I am currently with the section of code and my ideas on how to make this work using an array but I have been informed that saving/storing the data as an object might be a better option?
private void enterCar()
{
String carInfo;
int carHours;
int i = 0;
int[] carNumb = new int[20];
double fee = Double.parseDouble("7.50");
double sum = 0;
final int MAX = 12;
{
carInfo = JOptionPane.showInputDialog("Please enter the license plate of the car");
carHours = Integer.parseInt(JOptionPane.showInputDialog("Enter the number of hours the car was parked (1-12):"));
System.out.printf("\n");
System.out.printf("Details for car "+carNumb+" entered:\n");
System.out.printf("License plate Hours Fee:\n");
System.out.printf(""+carInfo+" "+carHours+" $");
if (carHours == 1)
System.out.printf("%3.2f",fee*(carHours));
else if (carNum == 2)
System.out.printf("%3.2f",fee+4.50);
else if (carHours >= 3)
System.out.printf("%3.2f",3+(carHours*4.50));
System.out.printf("\n\n");
}
}
When I compile and run the console I get the line "Details for car [I#6659c656 entered". This line does change to something like "[I#7665c575" the next time I activate the option so I can assume that I may need to assign a value to the number differently?
I have tried the option that is show in the code provided as well as trying to activate a list using (1, 2, 3, ect) but this also just outputs that random line of numbers and letters.
I guess to simplify my question. I need to store 20 individual inputs from an 'InputDialog' box and store it for later access in a console.
I need to store 20 individual inputs from an InputDialog box and store it for later access in a console.
Use a loop such as for.
That information then gets stored as "Details for car 1 entered:" and then the information displayed.
As I said before, you should use index of array instead of array. And because array is zero-based index, so I use carNumb[i] + 1 to print out the order.
Then calculate fee and store to carNumb array.
Note that, your fee is double type => carNumb should be double type to store correct value.
Full code:
public void enterCar() {
String carInfo;
int carHours;
int i = 0;
double[] carNumb = new double[20];
double fee = Double.parseDouble("7.50");
double sum = 0;
final int MAX = 12;
for (; i < carNumb.length; i++) {
carInfo = JOptionPane.showInputDialog("Please enter the license plate of the car");
carHours = Integer.parseInt(JOptionPane.showInputDialog("Enter the number of hours the car was parked (1-12):"));
System.out.printf("\n");
System.out.printf("Details for car " + (carNumb[i] + 1) + " entered:\n");
System.out.printf("License plate Hours Fee:\n");
System.out.printf("" + carInfo + " " + carHours + " $");
carNumb[i] = getFee(fee, carHours);
System.out.printf("%3.2f", carNumb[i]);
System.out.printf("\n\n");
}
}
private double getFee(double fee, int hours) {
if (hours == 1) {
return fee;
}
if (hours == 2) {
return fee + 4.5;
}
if (hours >= 3) {
return 3 + hours * 4.5;
}
return 0;
}
Did I get your idea?
Related
I was wondering whether it is possible to turn this code into a for loop. I know that you could loop the text, however, is it possible to do something similar to the variables inputRangeCity1, inputRangeCity2 etc..
System.out.print("Enter maximum cell phone connectivity distance for city 1: ");
double inputRangeCity1 = user_input.nextDouble();
System.out.print("Enter maximum cell phone connectivity distance for city 2: ");
double inputRangeCity2 = user_input.nextDouble();
System.out.print("Enter maximum cell phone connectivity distance for city 3: ");
double inputRangeCity3 = user_input.nextDouble();
System.out.print("Enter maximum cell phone connectivity distance for city 4: ");
double inputRangeCity4 = user_input.nextDouble();
If you declare inputRangeCity1, etc as separate local variables, it is next to impossible to use a loop.
If you declare inputRangeCity1, etc as separate instance (or class) variables, it is possible to use reflection. However, it is not a good solution ... because the code will be more complex, more verbose and fragile.
The best / simplest solution is to use an array rather than separate variables:
double[] inputRangeCities = new double[NOS_CITIES];
and then:
for (int i = 1; i <= inputRangeCities.length; i++) {
System.out.print("Enter maximum cell phone connectivity " +
"distance for city " + i + ": ");
inputRangeCities[i - 1] = user_input.nextDouble();
}
If the number of cities is not known (fixed) at the point where you need to declare the variable, then you should use a List instead. Otherwise, an array is better ... unless there is some other part of the application wthat would benefit from using a list.
If the array / collection approach is not what you need, then consider refactoring like this:
private double readRange(Scanner input, int cityNo) {
System.out.print("Enter maximum cell phone connectivity " +
"distance for city " + i + ": ");
return input.nextDouble();
}
...
double inputRangeCity1 = readRange(user_input, 1);
double inputRangeCity2 = readRange(user_input, 2);
double inputRangeCity3 = readRange(user_input, 3);
double inputRangeCity4 = readRange(user_input, 4);
It is more lines of code ... and I don't like it ... but it is an alternative.
Use a list instead of individual variables.
List<Double> inputRangeCities = new ArrayList<Double>();
for(int i=1; i <= 4; i++)
{
System.out.print("Enter maximum cell phone connectivity distance for city" + i);
inputRangeCities.add(user_input.nextDouble());
}
You can then for example access the value for the first city as inputRangeCities.get(0). Note that the index in a Java list or array always starts at 0.
I'm trying to calculate something properly. A user enters an amount of trees they want to plant, and there is a rule that a certain percent of trees die every single year. It says after 7 years the trees are sellable. To find the minimum number of seeds needed, you'd take however many die over the course of 7 years for each tree type, and add that to the initial number the user inputted, right?
Well, this is what I get when i enter 20,40,30 for each tree type respectively:
I get the same number of minimum seeds regardless. I assume this has to do with my index or something in my for loop. I'd just like to know how to properly calculate this.
The other issue: I am trying to format my output properly so that it tabs over for each variable so it doesn't look so ugly the way it does. I tried "\t" but it did nothing. How do I fix this, and the calculations so that each iteration is actually kept track of in the end? should I be using decayRate[i], desiredYield[i] etc instead of desiredYield[index] etc?
public class TreeCalc {
public static void main(String[] args){
//Initializes methods and arrays
String[] treeTypes = new String[] {"Fir", "Pine", "Spruce"};
int[] desiredYield = new int [treeTypes.length];
double[] decayRate = new double[] {0.07, 0.12, 0.08};
desiredYield = getYield(decayRate, desiredYield, treeTypes);
int[] data = getCalculate(decayRate, desiredYield, treeTypes);
printMessage(decayRate, desiredYield, treeTypes);
}
//Asks user to input # of trees for each tree type
public static int[] getYield(double[]decayRate, int[] desiredYield, String[]treeTypes) {
int index= 0;
for(int i=0;i < treeTypes.length;i++) {
try {
desiredYield[index] = Integer.parseInt(JOptionPane.showInputDialog("Please enter your desired yield for: " +treeTypes[i]));
//Catches any non-number input, displays error to user
} catch(NumberFormatException e){
desiredYield[index] = 0;
JOptionPane.showMessageDialog(null, "Error: Please enter your desired yield for "+treeTypes[i]);
}
if (desiredYield[index] <= 0) {
JOptionPane.showMessageDialog(null, "Error: Please enter your desired yield for "+treeTypes[i]);
} else{
index++;
}
}
return desiredYield;
}
//Calculates totals and minimums
public static int[] getCalculate(double[]decayRate, int[]desiredYield, String[]treeTypes){
int totalSeeds =0;
int totalTrees=0;
int minSeeds=0;
int index=0;
//For each iteration of the loop, calculates totals/mins
for(int i = 0; i < treeTypes.length; i++){
minSeeds += (desiredYield[index] * (decayRate[index]*7)) + desiredYield[index];
totalSeeds += minSeeds;
totalTrees += desiredYield[index];
}
return new int[] {totalSeeds, totalTrees, minSeeds};
}
//Prints the totals, minimums, and input from the user
public static void printMessage(double[]decayRate, int[]desiredYield, String[]treeTypes){
//Calls method and stores values within array
int[]data = getCalculate(decayRate, desiredYield, treeTypes);
int totalSeeds = data[0];
int totalTrees = data[1];
int minSeeds = data[2];
//Report displays after user is done entering inputs
String treeReport = "Tree Type | Desired Yield | Minimum Seeds | Total Seeds | Total Trees ";
for(int i=0; i<treeTypes.length; i++){
treeReport += "\n"+treeTypes[i] + " "+desiredYield[i] + " "+minSeeds + " "+totalSeeds + " "+totalTrees;
}
JOptionPane.showMessageDialog(null, treeReport);
}
}
No, your equation for the minimum number of seeds needed is not correct. You need something like M=Y/((1-r)^7) Where r is the proportion of trees that die each year, and Y is the desired yield. You solve for M, the minimum # of seeds.
For this program we are supposed to calculate the total price of items entered by the user. We are using methods for getting a ranged double and a method that asks the user if they want to continue. Here are the methods I am using:
public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
{
double retVal = lo - 1;
String trash;
do
{
System.out.print(prompt + " " + lo + " - " + hi);
if(src.hasNextInt())
{
retVal = src.nextInt();
}
else
{
trash = src.nextLine();
}
}while(retVal < lo || retVal > hi);
return retVal;
}
public static Boolean getYNConfirm(Scanner src, String prompt)
{
String input = "";
boolean done=true;
System.out.println(prompt + " Y or N");
while(!done)
{
input = src.nextLine();
if(input.equalsIgnoreCase("Y"))
{
done=true;
}
else if(input.equalsIgnoreCase("N"))
{
done=false;
}
else
{
System.out.println("Y or N");
}
}
return done;
}
And here is the description straight from my assignment:
At the 10$ store nothing is more than $10.00. Prompt the user for the
price of their item (.50 cents to $9.99 dollars) using the
getRangedDouble method and continue to input items as long as they
indicate that they have more using your getYNConfirm method. Display
the total cost of the item(s) to 2 decimal places with printf.
I know how to use the methods in the program but I have no idea how to get the getYNConfirm method to work or how to calculate the total price as the user enters the separate prices. Any help would be greatly appreciated.
Alrighty, so let's jump into your question:
At the 10$ store nothing is more than $10.00. Prompt the user for the price of their item (.50 cents to $9.99 dollars) using the getRangedDouble method and continue to input items as long as they indicate that they have more using your getYNConfirm method. Display the total cost of the item(s) to 2 decimal places with printf.
The first big thing to do with just about any coding question at this level is break it up into its constituent parts. For this question, those are:
Be able to ask the user for the price of an item (check)
Be able to ask the user if they have another item to enter (check-ish... see below)
Loop the above 2 steps as long as the second is true (TODO)
Be able to sum the values given in each price step of the loop (TODO)
For step 1, we have the getRangedDouble(...), which checks out. Here it is copied for convenience:
public static double getRangedDouble(Scanner src, String prompt, double lo, double hi){
double retVal = lo - 1;
String trash;
do{
System.out.print(prompt + " " + lo + " - " + hi);
if(src.hasNextInt()){
retVal = src.nextInt();
} else {
trash = src.nextLine();
}
} while(retVal < lo || retVal > hi);
return retVal;
}
For step 2, we have the getYNConfirm(...) method, given here:
public static Boolean getYNConfirm(Scanner src, String prompt){
String input = "";
boolean done=true;
System.out.println(prompt + " Y or N");
while(!done){
input = src.nextLine();
if(input.equalsIgnoreCase("Y")){
done=true;
} else if(input.equalsIgnoreCase("N")) {
done=false;
} else {
System.out.println("Y or N");
}
}
return done;
}
Unfortunately, this has a logical bug in it. You initialized done to true, and your while loop is over the condition while(!done). Thus the first time this is while(!true) --> while(false), which doesn't execute. So the while loop will never be entered, thus we return true every time you call the method. To fix this, consider what you do once you see a "Y" - you eventually return true. Your method goes through the motions of breaking the loop first, but we could just skip that step and jump straight to returning true. Thus consider this version of the getYN... method:
public static boolean getYNConfirm(Scanner src, String prompt){
String input = "";
System.out.println(prompt + " Y or N");
while(true){ //Loops forever until a return or break statement
input = src.nextLine();
if(input.equalsIgnoreCase("Y")){
return true;
} else if(input.equalsIgnoreCase("N")) {
return false;
} else {
System.out.println("Y or N");
}
}
}
This matches the intention of your original version of the method, without the logical bug.
So now we are on to our big finale - write a method using the above two methods as helpers that loops and continually asks the user for more prices, summing as it goes. Let's write this method as main(String[] args), just so we can run it and see what happens.
We want to use a loop here, in order to allow the user to continue to input prices until they are done. We can model our problem with psuedocode as follows:
while(user not done inputting prices){
get next price
add price to sum of prices
ask the user if they would like to continue
}
print sum of prices
Just like you can call a built in method and store the results of the output such as rentVal = src.nextInt(), you can do the same with methods you've written. For example, we can ask for the user to input the next price with getRangedDouble(...). By the method header we wrote, this returns a value of type double, so when we store the output of this call it should be in a double variable: double nextPrice = getRangedDouble(...);
If the psuedocode makes sense, the code that follows is actually relatively simple:
public static void main(String[] args){
Scanner s = new Scanner(System.in); //Allow for reading user input from console
boolean looping = true; //True so long as the user isn't done inputting prices.
//Initially true so that at least one price is entered
double sum = 0.0; //The sum of prices thus far
while(looping){
double nextPrice = getRangedDouble(s, "Enter a price in the range", 0.5, 10.0);
sum = sum + nextPrice; //Add the price into the sum
looping = getYNConfirm(s, "Add another item to your cart?");
}
System.out.println(String.format("%.2f", sum)); //Prints sum, limited to 2 decimal places
}
I don't see why this is an invalid answer. I feel the code is very self explanatory here. I added some additional reasoning but I'm glad to explain if there's anything wrong with it
So the code is as follows.
public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
{
boolean valid = false;
while( !valid ) {
System.out.print(prompt + " " + lo + " - " + hi);
if(src.hasNextInt())
retVal = src.nextInt();
else
src.nextLine();
if( retVal < 10 && retVal > 0.5 )
valid = true;
}
return retVal;
}
public static Boolean getYNConfirm(Scanner src, String prompt)
{
String input;
boolean done = false;
double total;
DecimalFormat df=new DecimalFormat("#.##");
while(!done) {
System.out.println("Y or N");
input = src.nextLine();
if(input.equalsIgnoreCase("Y"))
done=true;
else if(input.equalsIgnoreCase("N")) {
done=false;
total += getRangedDouble( file, "Specify the price between:", 0.50, 9.99);
System.out.println( "The total is:" + df.format( total ) );
}
}
return done;
}
Essentially you want to call getRangedDouble to ask the user to specify the price. You do that by adding the return
total += getRangedDouble
The parameters you want to feed are the Scanner, prompt, low, and high limits.
( file, "Specify the price between:", 0.50, 9.99);
In getRangedDouble, you want to get the user input while the response is not valid. So you were right, just keep reading until there's a next good hint.
Afterwards get and check their price input until you get the desired price range.
retVal < 10 && retVal > 0.5
When that happens, it's valid. Set the value to true, and return retVal. To format the total, all you need to do is use DecimalFormat. This line creates the decimal formate with #.## specifying a 2 decimal place precision.
DecimalFormat df=new DecimalFormat("#.##");
then you can call df.format( total ) to format your total while printing it.
I only see one usage of your getYNConfirm method (which is strange), but there's a rather subtle logic bug buried in it.
Observe:
while(!done)
If done is true, then the expression above reads:
while(false)
...which indicates that this loop will never be executed.
From what you've shown us thus far, the solution is as simple as converting the initial state of done to false:
boolean done = false;
As an aside, generally you want to return the boxed types for primitives when you absolutely must. In this scenario, I wouldn't see any value in you returning a Boolean as opposed to boolean.
I need to use a 2 dimensional array as part of the assignment.
I need to Declare variables at the beginning of the main method for a row counter and a rectangular array of strings that provides for 10 rows and 4 columns
After the code that calculates, formats, and displays the resutls for each calculation, add code that stores the formatted values as strings in the next row of the array ( you need to use the toString method of the integer class to store the years value).
I've already declared an array of 10x4 and a variable for a counter,
but I have a problem with adding code that stores the formatted values as strings in the next row of the array ( you need to use the toString method of the integer class to store the years value).
heres what i've coded below for this question(2) which seems to print a list of nulls, how do I get my code to print the table? this code below seems to me as the one causing the issues is it correct? am a bit confused.
FutureValueArray[counter][0] = Double.toString(monthlyInvestment);
FutureValueArray[counter][1] = Double.toString(interestRate);
FutureValueArray[counter][2] = Integer.toString(years);
FutureValueArray[counter][3] = Double.toString(futureValue);
/*This is how my table should look like.
Inv/Mo. Rate Years Future Value
$100.00 8.0% 10 $18.416.57
$125.00 8.0% 10 $23,020.71*/
public static void main(String[] args)
{
String[][] FutureValueArray = new String [10][4];
int counter = 0;
// display a welcome message
System.out.println("Welcome to the Future Value Calculator");
System.out.println();
// perform 1 or more calculations
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);
// calculate the future value
double monthlyInterestRate = interestRate/12/100;
int months = years * 12;
double futureValue = calculateFutureValue(
monthlyInvestment, monthlyInterestRate, months);
// get the currency and percent formatters
NumberFormat currency = NumberFormat.getCurrencyInstance();
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(1);
// format the result as a single string
String results =
"Monthly investment:\t"
+ currency.format(monthlyInvestment) + "\n"
+ "Yearly interest rate:\t"
+ percent.format(interestRate/100) + "\n"
+ "Number of years:\t"
+ years + "\n"
+ "Future value:\t\t"
+ currency.format(futureValue) + "\n";
// print the results
System.out.println();
System.out.println("FORMATTED RESULTS");
System.out.println(results);
FutureValueArray[counter][0] = Double.toString(monthlyInvestment);
FutureValueArray[counter][1] = Double.toString(interestRate);
FutureValueArray[counter][2] = Integer.toString(years);
FutureValueArray[counter][3] = Double.toString(futureValue);
for(int i = 0; i < FutureValueArray.length; i++)
{
for (int j = 0; j < FutureValueArray[i].length; j++)
System.out.println(FutureValueArray[i][j] + " ");
System.out.println("\n");
}
// see if the user wants to continue
System.out.print("Continue? (y/n): ");
choice = sc.next();
counter++;
System.out.println();
}
}
Your code seems fine.
If you change
for(int i = 0; i < FutureValueArray.length; i++)
To
for(int i = 0; i <= counter; i++)
You won't print the nulls of the FutureValueArray rows that have not yet been set.
Also, it looks like you want to use the System.out.print() function inside that loop, rather than the System.out.println() function.
I was going through a code used to calculate investments until it has doubled and I received an infinite loop that I can't seem to solve. Can anyone figure out why this is giving me an infinite loop? I've gone through myself but I can't seem to find the problem. The "period" referred is how many times per year the interest is compounded.
double account = 0; //declares the variables to be used
double base = 0;
double interest = 0;
double rate = 0;
double result = 0;
double times = 0;
int years = 0;
int j;
System.out.println("This is a program that calculates interest.");
Scanner kbReader = new Scanner(System.in); //enters in all data
System.out.print("Enter account balance: ");
account = kbReader.nextDouble();
System.out.print("Enter interest rate (as decimal): ");
rate = kbReader.nextDouble();
System.out.println(" " + "Years to double" + " " + "Ending balance");
base = account;
result = account;
for (j=0; j<3; j++){
System.out.print("Enter period: ");
times = kbReader.nextDouble();
while (account < base*2){
interest = account * rate / times;
account = interest + base;
years++;
}
account = (((int)(account * 100))/100.0);
//results
System.out.print(" " + i + " " + account + "\n");
account = result;
}
The code should ask for three "periods", or three different times the entered data is compounded per year (ex annually, monthly, daily etc.)
Thanks a lot!
Instead of doing
account =interest +base
You should have
account = interest +account
You should add some sanity checking. Either check if all the numbers will result in a finite number of loops (account and rate != 0, maybe some other stuff), or more simply, break if you've looped more times than would be reasonable (say 1000 for instance). My guess is that rate is 0 resulting in no increase in account, therefore it will loop forever.
You have a calculation error:
account = interest + base;
Presumably this should be:
account = account + interest;
Also, are you sure you want to have the int cast?
account = (((int)(account * 100))/100.0);
You're throwing away the values smaller than 1 cent apparently. However, if the interest is too small you will not get any change.
The reason it may loop forever is that the double calculation of account is effectively truncated by casting to int, so it may never change if rate is too small and the new value of account isn't made larger by at least 0.005.