This is a pretty common problem I run into when I'm programming, and I'm a beginner so it stumps me for whatever reason. Here's my code:
boolean valid = false;
do {
double newPrice;
System.out.print("Enter new price: $");
newPrice = scan.nextDouble();
if(newPrice > 0){
b[bookChosen].price() = new newPrice;
valid = true;
}
}while(!valid);
The newPrice double in the if-statement cannot be found, and I know why, I just can't think of a way to be able to see if the user's input is a viable number.
Thanks in advance.
You've got a couple of fundamental things wrong with your code, all centered on the line:
b[bookChosen].price() = new newPrice;
First of all, new newPrice doesn't do anything and won't even compile. new is a keyword for creating new objects, and must be followed with an invocation of a class's constructor -- newPrice is not a class, nor is it an invocation of a class's constructor.
Secondly, you're attempting to assign to the invocation of an object's method. You cannot assign to an invocation of an object's method -- you can only assign to names.
What you probably meant to do is something like:
b[bookChosen].setPrice(newPrice);
This uses a setter to set the price of the object contained at b[bookChosen]. Using setters to change the property of an object is an extremely common convention in Java. You probably wouldn't be having these issues if you were using an IDE, which is the only way anyone ever really writes modern Java (enter obligatory plug for https://www.jetbrains.com/idea/), and you'd probably learn a whole lot.
Other than that, your code is generally fine, although I think it's a little simpler written:
while (true) {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
if (newPrice > 0) {
b[bookChosen].setPrice(newPrice);
break; // leave while True loop
}
}
An alternative control flow that's not quite as natural for me, is:
double newPrice = 0;
while (newPrice <= 0) {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
}
b[bookChosen].setPrice(newPrice);
new newPrice;
new keyword is always used to create a new object not to assign a new value (this is what i understanded from your code)
b[bookChosen].price()
of what ever class b is the array of that. You are assigning a value to that at the index bookChosen.
If price is you method, then values are not assigned to methods, values are send through parameters to method.
like b[bookChosen].price(newPrice);
If price is your field of that class, then it must b public or protected if it is in the same package. then variables of class are
not post pended by (). they are assigned like b[bookChosen].price = newPrice;
but it not standard always make your bean by private fields and access then through setter getters.
boolean valid = false;
do {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
if(newPrice > 0){
b[bookChosen].setPrice(newPrice) ;
valid = true;
}
}while(!valid);
Best Of Luck.
Related
I'm decently new to programming, and I'm taking an introductory course at my high school right now. One of the assignments we're working on right now is a program that asks the user what formula they would like to calculate (various area/volume/etc types of formulas), asks them for the data needed to make the calculation, and then gives them the answer. I've gotten really interested in programming mostly due to this assignment, because I've realized just how much of a brain teaser this work can be.
With that, I decided to go a little bit above and beyond. I cleaned up my messy code, and I'm now trying to make a while loop that will allow the user to continue calculating formulas without running the program again, as well as give them an error message when they input improper data. I've figured out the latter part, but I want to implement the former before putting the solution to the second issue into the code.
import java.util.Scanner;
public class FormulaRemake {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n","What formula would you like to calculate?","Area of a Circle (AOC)","Circumference of a Circle (COC)","Area of a Trapezoid (AOT)","Volume of a Cylinder (VOC)","Volume of a Sphere (VOS)","Volume of a Cone (VON)");
String formula = input.nextLine();
while((formula.equalsIgnoreCase("AOC"))||(formula.equalsIgnoreCase("COC"))||(formula.equalsIgnoreCase("AOT"))||(formula.equalsIgnoreCase("VOC"))||(formula.equalsIgnoreCase("VOS"))||(formula.equalsIgnoreCase("VON")))
{
if(formula.equalsIgnoreCase("AOC"))
{
System.out.println("What is the circle's radius?");
double inputRadius = input.nextDouble();
System.out.printf("%.2f",Math.PI*(Math.pow(inputRadius,2)));
}
if(formula.equalsIgnoreCase("COC"))
{
System.out.print("What is the circle's radius?");
double inputRadius = input.nextDouble();
System.out.printf("%.2f",2*Math.PI*inputRadius);
}
if(formula.equalsIgnoreCase("AOT"))
{
System.out.println("What is the height of the trapezoid?");
double inputHeight = input.nextDouble();
System.out.println("What is the first length of the trapezoid?");
double inputLengthFirst = input.nextDouble();
System.out.println("What is the second length of the trapezoid?");
double inputLengthSecond = input.nextDouble();
System.out.printf("%.2f",(1/2)*inputHeight*(inputLengthFirst+inputLengthSecond));
}
if(formula.equalsIgnoreCase("VOC"))
{
System.out.println("What is the cylinder's radius?");
double inputRadius = input.nextDouble();
System.out.println("What is the cylinder's height?");
double inputHeight = input.nextDouble();
System.out.printf("%.2f",(Math.PI*(Math.pow(inputRadius,2)*inputHeight)));
}
if(formula.equalsIgnoreCase("VOS"))
{
System.out.println("What is the sphere's radius?");
double inputRadius = input.nextDouble();
System.out.println(( 4.0 / 3.0 ) * Math.PI * Math.pow( inputRadius, 3 ));
System.out.printf("%.2f",(4.0/3.0)*Math.PI*Math.pow(inputRadius, 3));
}
if(formula.equalsIgnoreCase("VON"))
{
System.out.println("What is the cone's radius?");
double inputRadius = input.nextDouble();
System.out.println("What is the cone's height?");
double inputHeight = input.nextDouble();
System.out.printf("%.2f",(1.0/3.0)*Math.PI*(Math.pow(inputRadius,2)*inputHeight));
}
}
}
}
I have a while line, but I'm not really sure what to do with it. I don't know how to make my code loop while (hehe, while) the active line is within the while block. Should I be saving this class, creating a new class, then referencing it in another class, like
string mathDone = true (at the end of every equation)
while(mathDone.equalsIgnoreCase(true))
{
String continueCalculation = input.nextLine;
System.out.println("Would you like to continue calculation?");
if(continueCalculation.equalsIgnoreCase("yes"))||(continueCalulation.equalsIgnoreCase("y"))
{
(whatever the run command is goes here) formulaRemake
}
}
asides from that, I'm kind of clueless. I know there are posts on stackoverflow on a similar topic, but I can't figure out how to apply them to my situation. I'm too new (and clearly, too stupid) to figure out how to use those posts to help me.
What you are asking for is kind of a menu, even though it would be with only two options:
Choose and calculate a formula
Quit
The code for the first option is already available. I assume that it works properly. The fastest way (but not recommended) would be to put your entire code in a while loop. I would recommend you to let the main function only have this while loop, which calls another function, where you put in your current code. If you do not know what functions are yet: they are helpful in many ways and one of them is to make code more readable, since you keep the essential part of your code at one place. For example if you have a very long math task, which is needed to be calculated in many places in your code, it would be better to not copy this calculation into every single part, where it is needed and you could call many code lines with only one line.
EDIT for clarification:
The way your program is now, with everything being in one function (the main function), will just get longer if you keep programing this way. The occurring problems here are, that the longer your code gets, the less readable and maintainable it becomes. While this may not be a problem for a little testing program, you will encounter the mentioned problems in a group project or in a company etc.
To deal with these problems you can change your code by adding functions, which is probably the next chapter you should check out. Functions/Methods are parts of the code, which can be called from every place, where you allow it. This is what a function basically looks like:
visibility static/nonStatic type functionName (parameterType parameterName) {
//codebody
}
visibility: either public, private, package (if omitted) or protected
We will use only public right now, which means, that the function is available everywhere.
static or nonStatic (if omitted): static means "once per class", which makes the function available either by an instance (nonStatic) or the class (static). But this is not that important for you now.
Type: The return type of the function. You can choose one datatype and return an instance of the chosen class/datatype to the point where the function was called. If nothing shall/must be returned, you can chose the type void.
functionName: can be chosen freely. Note: Use camelCase
Parameter list: (parameterType1 param1, parameterType2 param2, ... ), e.g. (int a, String b). In the function you have an int a now and a String b.
Your program would then look like this:
//Now your calculations etc are put into this function.
//Now you can write simply myFunction() somewhere else (outside of this function)
//and the execution of the code where the function is called will be
//stopped and wait until the function is finished (until the code of
//the function is executed)
public static void myFunction() {
Scanner input = new Scanner(System.in);
System.out.printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n","What formula would you like to calculate?","Area of a Circle (AOC)","Circumference of a Circle (COC)","Area of a Trapezoid (AOT)","Volume of a Cylinder (VOC)","Volume of a Sphere (VOS)","Volume of a Cone (VON)");
String formula = input.nextLine();
while((formula.equalsIgnoreCase("AOC"))||(formula.equalsIgnoreCase("COC"))||(formula.equalsIgnoreCase("AOT"))||(formula.equalsIgnoreCase("VOC"))||(formula.equalsIgnoreCase("VOS"))||(formula.equalsIgnoreCase("VON")))
{
if(formula.equalsIgnoreCase("AOC"))
{
System.out.println("What is the circle's radius?");
double inputRadius = input.nextDouble();
System.out.printf("%.2f",Math.PI*(Math.pow(inputRadius,2)));
}
if(formula.equalsIgnoreCase("COC"))
{
System.out.print("What is the circle's radius?");
double inputRadius = input.nextDouble();
System.out.printf("%.2f",2*Math.PI*inputRadius);
}
if(formula.equalsIgnoreCase("AOT"))
{
System.out.println("What is the height of the trapezoid?");
double inputHeight = input.nextDouble();
System.out.println("What is the first length of the trapezoid?");
double inputLengthFirst = input.nextDouble();
System.out.println("What is the second length of the trapezoid?");
double inputLengthSecond = input.nextDouble();
System.out.printf("%.2f",(1/2)*inputHeight*(inputLengthFirst+inputLengthSecond));
}
if(formula.equalsIgnoreCase("VOC"))
{
System.out.println("What is the cylinder's radius?");
double inputRadius = input.nextDouble();
System.out.println("What is the cylinder's height?");
double inputHeight = input.nextDouble();
System.out.printf("%.2f",(Math.PI*(Math.pow(inputRadius,2)*inputHeight)));
}
if(formula.equalsIgnoreCase("VOS"))
{
System.out.println("What is the sphere's radius?");
double inputRadius = input.nextDouble();
System.out.println(( 4.0 / 3.0 ) * Math.PI * Math.pow( inputRadius, 3 ));
System.out.printf("%.2f",(4.0/3.0)*Math.PI*Math.pow(inputRadius, 3));
}
if(formula.equalsIgnoreCase("VON"))
{
System.out.println("What is the cone's radius?");
double inputRadius = input.nextDouble();
System.out.println("What is the cone's height?");
double inputHeight = input.nextDouble();
System.out.printf("%.2f",(1.0/3.0)*Math.PI*(Math.pow(inputRadius,2)*inputHeight));
}
}
}
public static void main(String[] args) { //the main function, containing only the menu loop
Scanner input = new Scanner(System.in);
boolean stop = false;
while(!stop) { //menu loop
myFunction(); //Your formulas will be calculated in this function
System.out.println("Do you want to calculate another formula? 0: no, 1: yes")//ask the user if another calculation shall be done
int userInput = input.nextInt();
if (userInput == 0) {//set stop accordingly, stop = true will exit the loop
stop = true;
} else if (userInput == 1) { //
stop = false;
}
}
}
One last thing I have to note: The function is still very long this way and very unreadable. Your next step could be to make the code more readable by further splitting the function into smaller functions (you can call a function inside of another function)
Use continue and break statement, for example:
i=input;
while(true)
{
if(i==1){break;}
else
{
i=input;
continue;
}
}
Why do some strings (e.g. topStudent1) have to be set to null, while others (e.g. name1) do not, in order to avoid a compiler error? Why do some doubles (e.g. highScore) have to be set to 0, while others (e.g. score1) do not, in order to avoid a compiler error?
public class Exercise05_09 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of students: ");
int numOfStudents = input.nextInt();
String name1;
String name2;
String topStudent1 = null;
String topStudent2 = null;
double score1;
double score2;
double highScore = 0;
double nextHighScore = 0;
int count = 2;
while (count <= numOfStudents) {
if (count == 2) {
System.out.println("Enter a student name: ");
name1 = input.next();
System.out.println("Enter a student score: ");
score1 = input.nextDouble();
System.out.println("Enter a student name: ");
name2 = input.next();
System.out.println("Enter a student score: ");
score2 = input.nextDouble();
if (score1 > score2) {
highScore = score1;
topStudent1 = name1;
nextHighScore = score2;
topStudent2 = name2;
}
else {
highScore = score2;
topStudent1 = name2;
nextHighScore = score1;
topStudent2 = name1;
}
}
else {
System.out.println("Enter a student name: ");
name1 = input.next();
System.out.println("Enter a student score: ");
score1 = input.nextDouble();
if (score1 > highScore) {
nextHighScore = highScore;
highScore = score1;
topStudent2 = topStudent1;
topStudent1 = name1;
}
else if (score1 > nextHighScore) {
nextHighScore = score1;
topStudent2 = name1;
}
}
count++;
}
System.out.printf("Top two students:\n%s's score is %3.1f\n%s's score is %3.1f\n", topStudent1, highScore, topStudent2, nextHighScore);
}
}
Thanks!!
All variables must be definitely assigned (JLS §16) before they are accessed, and the compiler verifies this:
Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs.
Since the while loop may not execute at all (e.g. user enters 1), the use of the 4 variables (e.g. topStudent1) in the printf statement requires that the variables are initialized outside the while loop.
Such initialization doesn't have to be on the declaration line, but doing it there is simpler.
In contrast, the other variables (e.g. name1), are not used after the while loop, but only inside the loop, and are definitely assigned right before they are used.
Let's look at the program the way the compiler would (in a highly simplified manner, of course). The first thing we see is variable declarations, some of which initialize their variables.
After that is a while loop. The general rule is that a while loop executes an unknown number of times, including zero. So we have to assume that it's possible it will not execute at all, meaning that any variables assigned within it may not be assigned at all.
Finally we have an output statement that uses four of your variables: topStudent1, topStudent2, highScore, and nextHighScore. These are precisely the ones that you found needed to be initialized. (Actually, they just need to be assigned somewhere before this statement.)
So what's going on? Since the compiler knows it will need a value in each of those four variables to support the printf, it needs to guarantee that those variables have been assigned somewhere. Assigning inside the while loop doesn't count, since (as far as the compiler knows) the while loop won't execute at all. If you don't initialize them when you declare them, and you don't assign them in a way that the compiler recognizes will always happen between declaring them and using them, the compiler takes the conservative view and decides that they might be uninitialized.
The reason is quite simple, you need to garante that some values you use are not going to explote your app because are not initialized Exception.
HOW?
like this:
when you do this:
System.out.printf("Top two students:\n%s's score is %3.1f\n%s's score is %3.1f\n", topStudent1, highScore, topStudent2, nextHighScore);
then you are using the variables and passing those as parameters, but they are not initialized, so the method printf, has no idea about what is goint to print at compiling time, therefore they must be initialized to something (in this case null can be accepted too).
this is because the ones you are required to set are in if and else blocks the compiler isn't sure whether they will be initialized so to stop an error it forces you to initialize them. The ones that don't require initialization are outside the if/else so they will be declared. I hope that helps
to clarify the compiler can see if they will definitely be initialized through your logic and if there is only a chance of it happening it will make sure it won't throw a null by forcing your to declare it.
members of the class (both static and dynamic) are assigned default values if you do not assign a value directly in the code where you define them. Parameters and variables in a method, however, are not assigned default values and need to be set to something (default value or other) before using
There is a standard Rules is ,
Local Variable/Instance ( which is declare inside method ) must be
initialized before use it.
so far, before use it must need to initialize it either by 0 or some value or by null.
Here's a quick question. How do I initialize a double to null? As in when the level is empty, it will require the user to input a data. Else, if the data has already been inputted, it will ask user to overwrite the save changes. From my code below, I can only run the "if(level == null){" and not the overwrite statement
public static void inValue() {
double level = null;
if(level == null){
System.out.println("Enter level: ");
level = sc.nextDouble();
pat1.setLevel(level);
break;
}
else{
System.out.println("Overwrite");
System.out.println("Enter level: ");
level = sc.nextDouble();
pat1.setLevel(level);
break;
}
}
Use a java.lang.Double instead of primitive double.
A Double extends Object and is nullable.
For instance:
Double level = null;
API here.
Notes
In your case, only the if statement will execute, since level is declared as null outside the if / else scope.
Your break statements are useless in this context.
To assign a nullvalue tu a double, you have to use the java.lang.Doubleclass.
But that's only one part of your problem.
Every time you call inValue(), you set your levelto null.
So level==null is always true.
You have to declare your levelobject outside this function so it will keep the previous value.
This is a homework question so preferably I would like to write as much code as possible, just need a pointer.
I have a class called Sandwich that has a Method to set a main Ingredient and a few other things -
public class Sandwich {
private String mainIngredient, bread;
String getMainIngredient(){
return mainIngredient;
}
void setMainIngredient(String mainIng){
mainIngredient = mainIng;
}
void setBread(String dough){
bread = dough;
}
void setPrice(double cost){
price = cost;
}
Now in another class TestSandwich I've initialized an Array, as part of the question;
Sandwich[] sandwiches = new Sandwich[5];
Now what I need to do is loop through and assign a value to mainIngredient and bread each time.
I think I would want to do something along the lines of this but I'm not really sure how to do it correctly.
for(int i = 0; i < 5; i++){
System.out.println("Insert a main ingredient");
String userInput = sc.next();
sandwiches[i].setBread(userInput);
System.out.println("Insert a bread");
userInput = sc.next();
sandwiches[i].setMainIngredient(userInput);
System.out.println(sandwiches[i].getMainIngredient());
System.out.println("");
}
The main issue is - sandwiches[i].setMainIngredient(userInput);
Im not really experienced with arrays and methods such as these so any help with the correct syntax would be great.
Thanks
Sandwich[] sandwiches = new Sandwich[5]; creates an array of 5 null references.
You need to initialise each element yourself; in your loop write
sandwiches[i] = new Sandwich();
else you'll get NullPointerExceptions. Once you've done that you can call the setting methods as you currently do. Going forward, you could declare a two argument constructor taking the bread and main ingredient as arguments. That's better style since (i) you avoid setters and (ii) the object being in an ill-defined state between construction and use.
Sandwich[] sandwiches = new Sandwich[5];
This allocates an array to hold 5 sandwiches, but it doesn't create any sandwiches. Just the array. You're on the right track to create the sandwiches in a loop.
When you write this loop, instead of iterating until 5, it's better to use sandwiches.length, so that if you want 10 instead of 5 sandwiches, you can change the number in one place instead of 2. It will be safer and less error-prone:
for (int i = 0; i < sandwiches.length; ++i) {
// TODO: get the ingredients from user
// ready to create the sandwich, yum yum
Sandwich sandwich = new Sandwich();
sandwich.setBread("...");
sandwich.setMainIngredient("...");
sandwiches[i] = sandwich;
}
In my do while loop, the body works fine initially, but when it loops, it prints the first two statements like it should but it does not allow me to enter the name instead it goes straight to enter pin and whatever I enter it skips the rest and asks me if I want another transaction.
I have an array object partially filed. The variables in the object are name, pin, account number and balance. When I add a new object and set the balance, the new balance I enter causes the balance for the previous objects to change as well. I think it has something to do with the balance variable being declared as static but I don't make it static, i can the error "Cannot make a static reference to the non-static method withdraw(double) from the type CustomerRecord". (SOLVED) Thank you.
public class BankCustomers
{
public static void main(String[] args)
//------------------------------------------------
//Part4: Find a customer record from anotherArray
//to do transaction(s) and update the record's balance
char repeat; // User control to repeat or quit
Scanner keyboard = new Scanner(System.in); //creating the scanner
String aName;
int aPin;
double aWithdraw;
double aDeposit;
do{
//Read customer information before search
System.out.println();
System.out.println("Lets make a transaction");
System.out.println("Enter customer full name");
aName = keyboard.nextLine( );
System.out.println("Enter Pin");
aPin = keyboard.nextInt();
//Search an Array for equal aName and aPin
for (int i = 0; i < index; i++)
{
CustomerRecord cRecord = anotherArray[i];
if((cRecord.getName().equalsIgnoreCase(aName)) && (cRecord.getPin() ==(aPin)))
{
System.out.println(cRecord);
System.out.println("Enter Withdraw Amount");
aWithdraw = keyboard.nextDouble();
CustomerRecord.withdraw(aWithdraw);
System.out.println("Enter Deposite Amount");
aDeposit = keyboard.nextDouble();
CustomerRecord.deposit(aDeposit);
System.out.println(cRecord);
}
}
System.out.println("\nAnother Transaction? (y for yes)");
repeat = keyboard.next().charAt(0);
}while(repeat == 'y' || repeat == 'Y');
//Print the records on screen
for (int i = 0; i < index; i++)
System.out.print(anotherArray[i]);
}
Remove the static from
private static double balance
and
public static void deposit(double aDeposit)
and
public static void withdraw(double aWithdraw)
you don't want them to be static as you are going to call these methods directly from the objects you created, so they will be specific to each CustomerRecord.
Then in your code, change these lines:
CustomerRecord.deposit(aDeposit);
CustomerRecord.withdraw(aDeposit);
by:
cRecord.deposit(aDeposit);
cRecord.withdraw(aDeposit);
The modifications made now will be applied to each CustomerRecord balance variable and not to a single balance variable (unique for the whole program) as it was the case when it was static.
public class CustomerRecord implements Serializable
{
private String name;
private int pin;
private int account;
private double balance;
}
public void deposit(double aDeposit)
{
balance = balance + aDeposit;
}
public void withdraw(double aWithdraw)
{
if (balance >= aWithdraw) balance = balance - aWithdraw;
else System.out.println("Withdraw cannot be negativeegative");
}
Make balance non-static, as you mentioned. This will fix the bug.
Make the CustomerRecord#deposit() and #withdraw() methods non-static as well. This will fix the compile error caused by #1.
You're correct that the problem is that you made things static. None of balance, deposit, withdraw should be static because all of them are things that apply to a particular customer record rather than to all customer records simultaneously.
The fact that your code doesn't work when you don't make them static is related to the way in which you're calling the withdraw method: CustomerRecord.withdraw(aWithdraw). Can you see what's wrong with that, now that your attention is drawn to it?
In your instance variables for CustomerRecord you have balance declared as a static variable.
This means that anytime you change balance in one instance of the class that it will change in all instances. For example, the deposit and withdraw methods.
I assume you needed to make balance static in order for these two methods to work, but you should just take the static declaration out of all three. Then, you need to change all calls from
CustomerRecord.withdraw();
CustomerRecord.deposit();
to use an instance of a class rather than just the static class. So,
// Whatever values you want here, you seem to have 4 already declared so you can use those
CustomerRecord c = new CustomerRecord("", 0, 0, 0);
c.withdraw();
c.deposit();
Your problem is twofold:
First, balance istatic, which means it is associated with the class, not any of its instances (objects), or in other terms it is shared between all instances of that class.
Second, as you pointed it out, your static method withdraw is accessing balance. The consideration about static applies here just as well -- the method is associated with the class, and cannot access memebers that are non-static.
To solve the second problem, remove static from the withdraw declaration (and remove static from balance as well. Thyis will make your code CustomerRecord.withdraw() not compile, becuase withdraw is now not associated with the class itself, but an instance of it. So you need to use an instance and call withdraw on that
cRecord.withdraw(aWithdraw);
Similarly for deposit