This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
I have a problem with the following code. It's supposed to ask the user a series of questions about students' test scores and return the average test score, this part is working okay.
My problem is that I'm supposed to use a "while-loop" which will run the program, then ask the user if they want the program to end. If they respond "no," then it should restart and ask for a new set of test scores, etc.
When I try to execute the program it works fine up until the part where it's supposed to restart. After printing out the average it will ask me if I want to close the program, but it won't allow me to type anything in. It's like the program is ending on it's own.
I've made some comments around the while loop explaining my logic as I suspect that's where the problem will be.
import java.util.Scanner;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class testScores {
public static void main(String[] args) {
NumberFormat formatter = new DecimalFormat("####.##");
Scanner keys = new Scanner(System.in);
// Initialize endProgram to "no"
String endProgram = "no";
// Declare there's going to be a string called end
String end;
double totalScore = 0;
double averageScore = 0;
do {
// Do all of this now before you check anything
int number = getNumber(keys);
totalScore = getScores(number, keys, totalScore);
averageScore = getAverage(totalScore, number, averageScore);
printAverage(averageScore, formatter);
System.out.println("Do you want to end the program?");
end = keys.nextLine();
// Now check if end and endProgram contain the same string
} while (end.equals(endProgram));
// Apparently not
}
public static int getNumber(Scanner keys) {
System.out.println("How many students took the test?");
int number = keys.nextInt();
return number;
}
public static double getScores(int number, Scanner keys, double totalScore) {
for(int counter = 1; counter <= number; counter++) {
System.out.println("Enter their score.");
double score = keys.nextDouble();
totalScore = totalScore + score;
}
return totalScore;
}
public static double getAverage(double totalScore, int number, double averageScore) {
averageScore = totalScore / number;
return averageScore;
}
public static void printAverage(double averageScore, NumberFormat formatter) {
System.out.println("The average is " + formatter.format(averageScore));
}
}
I've tried a few different things like using a while instead of a do-while, and switching out "end" for "endProgram" to have it check "endProgram" after resetting it's value, all with no success. If anyone could help me with this it would be greatly appreciated.
You should try something along this line. The gist is that - the do-while is wrong here because it checks against a non-existant String :
String end = "";
/* rest of variables */
while (!(end.equals(endProgram) )) {
// Do all of this now before you check anything
int number = getNumber(keys);
totalScore = getScores(number, keys, totalScore);
averageScore = getAverage(totalScore, number, averageScore);
printAverage(averageScore, formatter);
System.out.println("Do you want to end the program?");
end = keys.nextLine();
// Now check if end and endProgram contain the same string
}
Related
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
My Java code should let the user enter a number and then calculate the factorial of that number and I need to use "for loop" When I enter number 5 it tells me the factorial is 6 when it should be 120. I have tried to watch tutorials with factoring loop but they wont work, i think its because i have "do" command that gets values from calling
Here is the code:
static Scanner kboard = new Scanner(System.in); //variable to read in values
public static void main(String[] args) {
int choice = 0;
String dummy = "";
String forename = "";
String surname = "";
int number = 0;
do {
System.out.println("1. display the user name, 2. calculate factorial, 3. exit");
choice = kboard.nextInt();
dummy = kboard.nextLine(); //strips out the return
if (choice == 1) {
forename = getforename();
surname = getsurname();
displaydetails(forename, surname);
}
if (choice == 2) {
number = getnumber();
calcfactorial(number);
}
if (choice == 3) {
System.out.println("bye");
}
} while (choice != 3);
}
public static String getforename() {
String newforename = "";
System.out.println("Please enter your forename ?");
newforename = kboard.next();
return (newforename);
} // end getforename
public static String getsurname() {
/*
Code to prompt the user to enter a surname
*/
String newsurname = "";
System.out.println("Please enter your surname ?");
newsurname = kboard.next();
return (newsurname);
} // end getsurname
public static void displaydetails(String displayforename, String displaysurname) {
/*
Code will carry out prescribed changes and display the result
*/
char displayinitial;
String displayusername = "";
displaysurname = displaysurname.toUpperCase();
displayinitial = displayforename.charAt(0);
displayusername = displayinitial + displaysurname;
System.out.println("Your username is " + displayusername);
}
public static int getnumber() {
System.out.println("What numbers factorial do you want to know?");
int newnumber = kboard.nextInt();
return newnumber;
}
public static void calcfactorial(int newnumber) {
int count = 0;
int factorial = 1;
if (newnumber > 0) {
for (count = 1; count <= newnumber; count++); {
factorial = factorial * count;
System.out.println("Factorial of " + newnumber + " is: " + factorial);
}
} else {
System.out.println("Number must be positive");
}
}
If you had used a debugger, then you could tell that it's only executing the multiplication in the calcfactorial method once, and count is already 6 at this point. Reasons:
First, remove the semicolon at the end of the for condition loop. It is acting as the body of the for loop. This makes count equal to newnumber + 1, or 6.
Second, move your print statement after the end of the for loop, but still within the if block. Otherwise you'll get newnumber lines of printouts.
I am not going to fully give away the answer...user azurefrog posted a helpful link on debugging code.
However, your for loop is doing something you don't intend:
public static void calcfactorial(int newnumber)
{
int count = 0;
int factorial = 1;
if (newnumber > 0)
{
for (count=1;count<=newnumber;count++);
{
factorial = factorial * count; System.out.println("Factorial of "+newnumber+" is: "+factorial);
}
}
else
{
System.out.println("Number must be positive");
}
}
Reading through this, the line factorial = factorial * count; is just going to do 1*1, 1*2, 1*3, 1*4, 1*5, etc. for whatever is entered to be calculated for factorial. This is not the correct logic.
I recommend thinking through the logic of the for loop a bit more carefully. You should be using the number entered (i.e. 5 for the example you've given) somewhere in that loop.
Make a class that represents an average of test scores. Make the class take an unlimited number of scores and calculate the number of tests taken along with the average.
I cannot seem to be able to figure out a way to store all the test scores as well as to count the amount of tests from the given file. At the moment this code will only count one of the tests as well as only store the last number given.
This file is given by the instructor and cannot be changed
public class TestScoresDemo {
public static void main(String[] args) {
TestScores t1 = new TestScores("Alice");
TestScores t2 = new TestScores("Bob");
t1.addTestScore(50);
t1.addTestScore(60);
t1.addTestScore(54);
t1.addTestScore(73);
t1.addTestScore(88);
t1.addTestScore(92);
t2.addTestScore(87);
t2.addTestScore(97);
t2.addTestScore(37);
t2.addTestScore(99);
System.out.println("-- Alice --");
System.out.println("Num tests taken: " + t1.getNumTestsTaken());
System.out.println("Average: " + t1.getAverage());
System.out.println("-- Bob --");
System.out.println("Num tests taken: " + t2.getNumTestsTaken());
System.out.println("Average: " + t2.getAverage());
}
}
End of file given by instructor.
The following is what I have so far.
import java.util.Scanner;
public class TestScores {
private String Name;
private double TotalScore;
private int NumScores;
private double Earned;
public TestScores(String name) {
Name = name;
}
public void addTestScore(double earned) {
Earned = earned;
}
public int getNumTestsTaken() {
NumScores = 0;
while (Earned < 100.0) {
NumScores++;
}
return NumScores;
}
public double getAverage() {
try (Scanner scanner = new Scanner(Name)) {
double sum = 0.0;
while (Earned <100.0) {
sum += Earned;
TotalScore = sum / NumScores;
break;
}
return TotalScore;
}
}
}
You aren't using the variable NumScores or TotalScore correctly. Furthermore, you should use the Java naming conventions for variables so change the first letter in the name to a lowercase letter and then use capitol letters, AKA camel case. Try the following
public TestScores(String name) {
this.name = name;
numScores = 0;
totalScore = 0.0;
}
public void addTestScore(double earned) {
totalScore += earned; //add to the running total
numScores++; //add to the count
}
public int getNumTestsTaken() {
return numScores; //simply return the counter
}
public double getAverage() {
return totalScore/numScores; //return the total scores added up divided by the count
}
There are 2 approaches to solve this question, both have been discussed in the comments above:
Use a list / array / collection to store each value
Sum the numbers overtime when new element is added
As your requirement says that TestScores class cannot be changed, then it leaves 1st approach out of the possible solutions1, that makes the only one viable answer the 2nd approach.
But before writing the answer I'll rescue #Turing85's comment
A remark on your overall code design: variable- and field-names should always start with a lowercase letter (private String Name; -> private String name;).
So, your TestScores attributes might become:
private String name;
private double totalScore;
private int numScores;
private double earned;
This will make your program easier to read for you and all of us. Read and follow Java naming conventions.
Now let's see what your program is doing right now:
t1.addTestScore(50); //earned = 50
t1.addTestScore(60); //earned = 60
t1.addTestScore(54); //earned = 54
What you want:
t1.addTestScore(50); //earned = 50
t1.addTestScore(60); //earned = 110
t1.addTestScore(54); //earned = 164
All you have to do (after changing variable names to start with lower case letters) is:
public void addTestScore(double earned) {
this.earned += earned; //This will be adding every number you send to it to the total
this.numScores++; //This keeps track of the number of tests taken
}
Now getNumTestsTaken method might become something like:
public int getNumTestsTaken() {
return numScores;
}
And your getAverage method to become something like this:
public double getAverage() {
return earned / numScores; //We already know the total amount earned as it's stored in "earned" variable and the number of scores stored in "numScores" so, this becomes a simple operation
}
For the rest of the code, I think it's OK.
1 I'm leaving the array / collection out of this answer, but making this answer a community-wiki in case someone wants to add it as well as an answer. However I already explained the reason why this is not suitable here (as per OP's requirements).
I am making a simple average grade calculator. Basically takes in users mark and the percentage of that module and displays the average percentage. The program does work but it has a few glitches which happens in the while loop.
The while loop should end as soon as the user enters any value under -1 but it continues on for a few times and then exits the while loop. Also, it first lets the user enter a number to ensure to start the while loop and then the text 'Enter Mark' comes up which makes the user enter their marks again. Im trying to make the while loop automatically start but dont know how too.
import java.util.ArrayList;
import java.util.Scanner;
public class percentage {
static ArrayList<Double> marks = new ArrayList<>();
static ArrayList<Double> percentage = new ArrayList<>();
static Scanner input = new Scanner(System.in);
static void addingToMarks(double currentmark) {
marks.add(currentmark);
}
public static void main(String[] args) {
System.out
.println("Type in the number of marks you got \n"
+ "in the module. And then type the percentage weight of it.\n"
);
double exitLoop = input.nextDouble();
while (exitLoop > -1) {
System.out.println("Type in your marks");
marks.add(input.nextDouble());
System.out
.println("Type in the weighted percentage of the module: ");
percentage.add(input.nextDouble());
exitLoop = input.nextDouble();
}
System.out.println(percentage);
System.out.println(marks);
System.out.println("Your average percent for the module is: "
+ gradeCalculate());
}
static double gradeCalculate() {
double totalaverageweight = 0;
for (int x = 0; x < marks.size(); x++) {
totalaverageweight += ((marks.get(x) / 100) * percentage.get(x));
}
return totalaverageweight;
}
}
I think a do... while loop will work in this case since the test condition will happen at the end of the loop
do{
////your code goes here
}while(exitLoop!=-1);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am working on an assignment and it is working well so far. But several aspects aren't working. For starters, my counters for int total and int counter won't work. Also my if statements don't seem to be working. I have been scratching my head for several days now.
The assignment calls for a program to input the order number and will loop based on how many orders the customer has. It also calls for customer name, sign type(wood or plastic), the number of characters,and color of characters.
Some more information:
The base price for all signs is $20.
If sign is wood, add $10. If it is plastic add $5.
The first 5 letters/numbers are included in base price, and $2 for each additional character.
Black or white characters are included in base price, there is an additional $8 for colored letters.
If the total charge is more than $100 give 25% discount on total price.
Here is my code right now:
import java.util.Scanner;
public class Carpenter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int orderNumber;
String custName;
String signType;
int numOfCharacters;
String color;
int i = 20;
double total;
int counter;
System.out.println("Enter your order number");
orderNumber = sc.nextInt();
counter=orderNumber;
counter--;
sc.nextLine();
System.out.println("Enter customer name");
custName = sc.next();
do{
System.out.println("Enter the sign type (wood or plastic)");
signType = sc.next();
if(signType == "wood") {
i+=10;
}
if(signType == "plastic") {
i+=5;
}
System.out.println("Enter the number of characters");
numOfCharacters = sc.nextInt();
if(numOfCharacters > 5) {
i += 2*(numOfCharacters-5);
}
System.out.println("Enter the color of characters");
color = sc.next();
if(color != "white" || color != "black") {
i += 8;
}
total= i;
System.out.println("Total is: $" + total);
if( total > 100 ) {
total = (total * 0.25);
System.out.println("The total is " + total );
}
}
while(counter <= orderNumber);
}
}
I added comments to guide you through the changes I made. Also, remember to call the sc.NextLine() function after you get user input so that they can input something different next time (this is called 'flushing' the buffer).
import java.util.Scanner;
public class Carpenter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int orderNumber;
String custName;
String signType;
int numOfCharacters;
String color;
int i = 20;
double total;
int counter;
//I changed the phrasing just because it is a little confusing
System.out.println("Enter your number of orders");
orderNumber = sc.nextInt();
counter = orderNumber;
sc.nextLine();
System.out.println("Enter customer name");
custName = sc.next();
sc.nextLine();
//When you know how many times you want to repeat something (like when a user tells you how many) I prefer using a for-loop, a do while loop works as well though
for(int x=0; x<counter;x++)
{
System.out.println("Enter the sign type (wood or plastic)");
signType = sc.next();
//When comparing Strings, there is a function that you can use to compare them rather than using '=='
// It is also good to use the 'equalsIgnoreCase()' function to be more user friendly and robust
if(signType.equalsIgnoreCase("wood")) {
i+=10;
}
if(signType.equalsIgnoreCase("plastic")) {
i+=5;
}
//Flush the buffer (I haven't tested if this is necessary or not, it is good practice though)
sc.nextLine();
System.out.println("Enter the number of characters");
numOfCharacters = sc.nextInt();
if(numOfCharacters > 5) {
i += 2*(numOfCharacters-5);
}
System.out.println("Enter the color of characters");
color = sc.next();
//Same concept as above, the differene is the ! before the function to test if it is false or not
if(!color.equalsIgnoreCase("white") || !color.equalsIgnoreCase("black")) {
i += 8;
}
}
total = i;
//You will not want to print this out until the end due to the possibility of it being over $100
// System.out.println("Total is: $" + total);
if( total > 100 ) {
//Mathematically speaking, you are making your total a quarter of what the original is, rather than taking a quarter off. You want 75% rather than 25%
// total = (total * 0.25);
total = (total * 0.75);
}
System.out.println("Total is: $" + total);
}
}
You should set counter to the correct starting value (which is presumably 1 in your case):
orderNumber = sc.nextInt();
counter=1;
//counter=orderNumber;
//counter--;
Then at the end of the loop, you should increment your counter:
do{
//code
counter++;
}
while(counter <= orderNumber);
This question already has answers here:
Error: 'else' without 'if' [closed]
(3 answers)
Closed 7 years ago.
At line 53 it is giving me an error of else without if. I clearly have an if statement, but i don't know what i'm doing wrong to make java not recognize it. I've tried moving around the braces and nothing is working.
import java.util.Scanner;
import java.text.DecimalFormat;
public class Quiz6
{
public static void displayInfo()
{
System.out.println(
"\n\tAuthor: Allen Watson \n" +
"\tClass: \tCSCI 1250-001 \n" +
"\tDate: \t10/09/2013 \n" +
"\tLab: \tQuiz6 \n");
}
public static double calculatePay(int hourWorked, double hourlyRate)
{
double dPay;
dPay = (hourWorked * hourlyRate);
return dPay;
}
public static void main(String[] args)
{
Scanner Keyboard = new Scanner(System.in);
DecimalFormat dfMoney = new DecimalFormat("$#,##0.00");
String strName;
int iCount;
int iDaysWorked;
int iTotalHoursWorked;
int iSingleDayHours;
double dHourlyRate;
final byte WEEK = 7;
displayInfo();
System.out.print("\tWhat is your name: ");
strName = Keyboard.nextLine();
System.out.print("\n\tHow many days did you work this week: ");
iDaysWorked = Keyboard.nextByte();
System.out.print("\n\tHow much do you make an hour: ");
dHourlyRate = Keyboard.nextDouble();
if(dDaysWorked <= WEEK);
{
for(iCount = 1; iCount <= iDaysWorked ; iCount++)
{
System.out.print("\tHow many hours did you work on the day"+iCount+":");
iSingleDayHours = Keyboard.nextInt();
iSingleDayHours += iTotalHoursWorked;
}
}
else
{
bDaysWorked = 0;
System.out.print("A week can only have seven days");
}
calculatePay(iTotalHoursWorked,dHourlyRate);
System.out.print("Hello "+strName+", you worked a total of "+iTotalHoursWorked+" hours over "+iDaysWorked+" days.");
System.out.print("\nWith am hourly rate of "+dfMoney(dHourlyRate)+" you made "+dfMoney(dPay)+".");
}
}
Here's the problem:
if(dDaysWorked <= WEEK); // remove the ;
That trailing ; is making Java believe that the if statement is finished, and the {} block after it is outside the if condition, consequently the else part has no matching if preceding it.
This is a rather frequent bug, and a hard one to spot. If it weren't for the else block, the code would have compiled correctly, but it would have been wrong. Bottom line: never, ever put a ; in the opening line of an if, for or while statement.
if(dDaysWorked <= WEEK); - remove last ;