I am getting an out of bonds error when I use this coding to get user input. The user input for noOfJudges is how long the array will be. For each judge a score is entered and tested to see if it is between 1 and 10.
Code:
double [] scores = new double [noOfJudges];
System.out.print("Please enter the next score: ");
for(scoreEntry = 0; scoreEntry < scores.length; scoreEntry++)
scores[scoreEntry]=console.nextDouble();
System.out.println();
while((scores[scoreEntry] < MIN_SCORE)||(scores[scoreEntry] > MAX_SCORE))
{
System.out.print("Please reenter the score (must be between 1.0 and 10.0, in .5 increments): ");
scores[scoreEntry] = console.nextDouble();
System.out.println();
}
If anyone wants to be totally great, is there a way to check to see if a number is between 1 and 10 and only in .5 increments?
You should use a local variable to the for loop or reset scoreEntry, because at the end of the for loop scoreEntry is equal to the length of the array, which is not a valid index...
After the for loop ends,
do a System.out.println(scoreEntry);
Therein lies your answer :)
Best,
Ankit
You must forgot a pair of {}
double[] scores = new double[noOfJudges];
System.out.print("Please enter the next score: ");
for(scoreEntry = 0; scoreEntry < scores.length; scoreEntry++) {
scores[scoreEntry] = console.nextDouble();
System.out.println();
while((scores[scoreEntry] < MIN_SCORE) || (scores[scoreEntry] > MAX_SCORE)){
System.out.print("Please reenter the score " +
"(must be between 1.0 and 10.0, in .5 increments): ");
scores[scoreEntry] = console.nextDouble();
System.out.println();
}
}
Related
I need to write a program that allows a student to enter up to 10 quiz scores, computes the average score, and then displays the letter grade based on the average. However, if the user enters 999 during the input of quiz scores, the program will terminate. This is the code block I wanted to insert a break statement into but I'm struggling to correctly incorporate grade[i] = 999 into my code without getting an error message. I think the issue may be that the 999 is an integer array value and is unrelated to the int i counter in the for loop.
for (i = 0; i < 10; i++) {
//prompts user to enter grade + displays counter value
System.out.print("Enter grade " + (i + 1) + " or enter 999 to quit: ");
//allows user input to be stored in variable grade
grade[i] = scanner.nextInt();
//adds new grade input to total grade to update variable gradeTotal
gradeTotal = gradeTotal + grade[i];
Assign the inputted value to a temporary variable, and then if it is 999 break the loop, else assign it the the array.
for (i = 0; i < 10; i++) {
System.out.print("Enter grade " + (i + 1) + " or enter 999 to quit: ");
int temp = scanner.nextInt();
if (temp == 999) {
break;
}
grade[i] = temp;
...
I am learning Java on my own and have just finished learning the basics of arrays, or so I think. I want to create a class grade sheet that keeps each student's grades and average. I have a for loop that asks each of the 10 students to enter their 4 test grades. Once I get those 4 grades, I take the average. I then store the student's grades and average into an array, one array per student. I essentially create 10 arrays with these 5 elements, for each student using the for loop. I now want to take the 5th element, the average of the 4 grades, from each student's array and populate another array called averages so I can perform other calculations. Is this possible with my logic? I think I could hard code 10 arrays, 1 for each student like so:
double averages[] = {student1[4], student2[4], ..., student10[4]};
Isn't this a bad way to go about this though? Any constructive help or guidance would be appreciated. Please do not post code that gives away the answer, as I won't learn from that. I just want a hint in the right direction. :)
Here's my code up until the point of confusion:
import java.util.Scanner;
public class ClassAverages {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
double grade1 = 0.0, grade2 = 0.0, grade3 = 0.0, grade4 = 0.0, average = 0.0;
// get grades from each of the 10 students
for (int student = 1; student <= 3; student++) {
System.out.println("Student " + student);
System.out.println("---------\n");
System.out.print("Enter the first grade: ");
grade1 = keyboard.nextDouble();
while (grade1 < 0) { // input validation for grade 1
System.out.print("You entered a negative value for grade. Please re-enter a positive grade: ");
grade1 = keyboard.nextDouble();
}
System.out.print("Enter the second grade: ");
grade2 = keyboard.nextDouble();
while (grade2 < 0) { // input validation for grade 2
System.out.print("You entered a negative value for grade. Please re-enter a positive grade: ");
grade2 = keyboard.nextDouble();
}
System.out.print("Enter the third grade: ");
grade3 = keyboard.nextDouble();
while (grade3 < 0) { // input validation for grade 3
System.out.print("You entered a negative value for grade. Please re-enter a positive grade: ");
grade3 = keyboard.nextDouble();
}
System.out.print("Enter the fourth grade: ");
grade4 = keyboard.nextDouble();
System.out.println();
while (grade4 < 0) { // input validation for grade 4
System.out.print("You entered a negative value for grade. Please re-enter a positive grade: ");
grade4 = keyboard.nextDouble();
System.out.println();
}
// calculate the current student's average
average = (grade1 + grade2 + grade3 + grade4) / 4;
// for each student, 1 to 10, create an array with their 4 grades and average
double studentX[] = { grade1, grade2, grade3, grade4, average };
System.out.println("SCORE 1\t\tSCORE 2\t\tSCORE 3\t\tSCORE 4\t\tAVERAGE");
System.out.print(studentX[0] + "\t\t");
System.out.print(studentX[1] + "\t\t");
System.out.print(studentX[2] + "\t\t");
System.out.print(studentX[3] + "\t\t");
System.out.print(studentX[4] + "\n");
System.out.println();
// I want to use each student's average for each corresponding element in the averages array
// create an array of all student's averages
// double averages[] = {student1average, student2average,...student10average} ???
}
}
}
OUTPUT AS OF NOW:
Student 1
---------
Enter the first grade: 100
Enter the second grade: 100
Enter the third grade: 100
Enter the fourth grade: 100
SCORE 1 SCORE 2 SCORE 3 SCORE 4 AVERAGE
100.0 100.0 100.0 100.0 100.0
Student 2
---------
Enter the first grade: 90
Enter the second grade: 90
Enter the third grade: 90
Enter the fourth grade: 80
SCORE 1 SCORE 2 SCORE 3 SCORE 4 AVERAGE
90.0 90.0 90.0 80.0 87.5
Student 3
---------
Enter the first grade: 100
Enter the second grade: 100
Enter the third grade: 90
Enter the fourth grade: 80
SCORE 1 SCORE 2 SCORE 3 SCORE 4 AVERAGE
100.0 100.0 90.0 80.0 92.5
You could use a for loop. However this will require you to have a collection of items to iterate through. I think the best way for you to do this is to organize your students into their own separate class (give that class all the grades as parameters in its constructor and have it do the calculations for average within that class).
So if you call your class student then your constructor could look like thisstudent(int grade1, int grade2, int grade3, int grade4). Use these parameters to calculate the average for each student object.
Then in your ClassAverage class just instantiate new student objects as you want and add them to an array of student objects and then its as simple as iterating through the array of student, extracting the average field that you created for each student object (extract this simply by stating studentName.average, assuming you named your average field average in the student class).
So by the end you should have something that looks like this. Let's assume that the array of student objects is called studentArray
int[] averageArray = new int[studentArray.length];
for (int i = 0; i < studentArray.length; i++){
averageArray[i] = studentArray[i].average;
}
Good luck!
Arrays are very bad form of storing information. Mostly because they don't contain logic that uses data inside this arrays and any other code can make that data invalid because array doesn't check what values you give it. This is what classes are for: to have data and code that works with it in one place, and to protect data from changes from other places in code.
So for your case arrays are OK for fields of the same type(for example, array of students is OK), but not for values of that types(array of arrays of students grades is NOT OK). So what you should do here is to use a class:
class Student
{
int grades[] = new int[4];
public Student(int grade1, grade2, int grade3, int grade4)
{
grades[0] = grade1;
grades[1]=grade2;
grades[2]=grade3;
grades[3]=grade4;
}
public double average()
{
double result = 0;
for(int i =0; i<grades.count; i++)
result += grades;
return result / grades / count;
}
// and so on
}
They allow you to take logic inside object, sou you can use it like this:
Student albert = new Student(5, 4, 2, 1);
System.out.println(albert.avarage()); // prints 3
I've seen several average calculators but none with this specific function.
Basically, I want it to ask "How many numbers would you like to average?" then "Enter your number" and continue to prompt "Enter your number" after each entry until the "How many numbers..." quantity is fulfilled. I know it's a count-loop (sorry if my jargon is off...I'm only in my second semester of computer programming) but I don't know how to set it up. Thanks in advance for your answers. Here's what I have so far:
import java.util.Scanner;
public class TestScoreApp
{
public static void main(String[] args)
{
// welcome the user to the program
System.out.println("Welcome to the Test Average Calculator!");
System.out.println(); // print a blank line
// display operational messages
System.out.println("Please enter test scores that range from 0 to 100.");
System.out.println(); // print a blank line
// initialize variables and create a Scanner object
int scoreTotal;
int scoreCount;
int testScore;
Scanner sc = new Scanner(System.in);
// perform calculations until choice isn't equal to "y" or "Y"
String choice = "y";
while (!choice.equalsIgnoreCase("n"))
{
// get the number of grades to be averaged from the user
System.out.print("How many scores would you like to average? ");
scoreCount = sc.nextInt();
// get the input from the user
System.out.print("Enter score: ");
testScore = sc.nextInt();
// accumulate score count and score total
if (testScore <= 100)
{
scoreTotal = scoreTotal + testScore;
}
else if (testScore >= 100)
System.out.println("Invalid entry, not counted");
// display the score count, score total, and average score
double averageScore = scoreTotal / scoreCount;
String message = "\n" +
"Score count: " + scoreCount + "\n"
+ "Score total: " + scoreTotal + "\n"
+ "Average score: " + averageScore + "\n";
System.out.println(message);
System.out.print("Would you like to average more grades? (y/n): ");
choice = sc.next();
System.out.println();
}
}
}
Your approach is near about right except some mistakes. You want to take input until 'n' is pressed and then the average would be shown. That means the average calculation must be done outside the loop, when taking input ends.
If you want to take input with a predefined number from input instead of 'y'/'n' approach, you can reuse your while loop:
int numOfInput = sc.nextInt(); // how many number will be entered
while(numOfInput > 0) {
// take every input and add to total
--numOfInput;
}
// average calculation
Also, a little logical mistake in input validation check.
if (testScore <= 100) // for less or equal 100
{
scoreTotal = scoreTotal + testScore;
}
else if (testScore >= 100) // for greater or equal 100
System.out.println("Invalid entry, not counted");
Both condition checks whether the number is equal to 100, which is not expected. If you allow only number less than 100, then you could write:
if (testScore < 100) {
scoreTotal += testScore;
}
else {
System.out.println("Invalid entry, not counted");
}
So you want to average scoreCount items, or keep averaging until the user has input "n" ?
If it's the first case (As you've described in your question) and you want to average for scoreCount times, you need to change the condition on your while loop.
System.out.print("How many scores would you like to average? ");
scoreCount = sc.nextInt();
scoreTotal = 0;
for(int i=0; i<scoreCount; i++){
scoreTotal += sc.nextInt();
System.out.print("Okay please enter next...");
}
System.out.print("Average is " + scoreTotal/scoreCount);
If you want to do it with a while, just keep an index, int index=0;, increment the index on each iteration and check if you've exceeded the index.
while (index < scoreCount)
scoreTotal += sc.nextInt();
index++;
System.out.print("Average is " + scoreTotal/scoreCount);
That is what you need:
for( int i = 0; i < scoreCount; i++){
System.out.print("Enter score: ");
testScore = sc.nextInt();
}
The for loop creates integer i to hold its looping index
int i;
And each loop asks is i bigger than scoreCount and if not loop again.
i < scoreCount;
And after each loop it adds one to i.
i++
I have a for-loop which asks for scores between 0 and 10. It asks a certain amount depending on the number of judges.
Here's the code:
System.out.println("Number of judges: ");
int numOfJudges = IO.readInt();
int sum = 0;
for (int i=0; i<numOfJudges; i++) {
System.out.print("Enter judge's score: ");
int score = IO.readInt();
if (score >= 0 && score <= 10) {
sum += score;
} else {
System.out.println("Incorrect number, must be between 0 and 10.");
}
}
System.out.println(sum);
I want to make is so if a number is entered that's not between 0 and 10, it won't count that as one of the conditions as i < numOfJudges.
For example if I have 3 judges and I enter 2 wrong inputs, it will still only run the loop 3 times (and only take the good input into account) while I really want it to run 5 times to make up for the two incorrect inputs.
Increment numOfJudges in case of ELSE condition so that your FOR loop would run until you have desired number of correct inputs.
This is shortest and cleanest solution.
else {
System.out.println("Incorrect number, must be between 0 and 10.");
numOfJudges++;
}
You can use a while loop inside of the for-loop, instead of adjusting the for-loop:
for (int i=0; i<numOfJudges; i++) {
while(true){
System.out.print("Enter judge's score: ");
int score = IO.readInt();
if (score >= 0 && score <= 10) {
sum += score;
break; //jump out of while-loop
}else {
System.out.println("Incorrect number, must be between 0 and 10.");
}
}
}
System.out.println(sum);
This is a program to calculate average grades and I cant figure out whats wrong with my code. It is returning the wrong answer.
Editing post to remove personal information.
:
/**
* This program will calculate grade average of user input
* Date: 10/2/2015
*/
import java.util.Scanner;
public class GradeAVG {
public static void main(String[] args) {
avgGrade();
}
public static void avgGrade() {
Scanner keyboard = new Scanner (System.in);
double count = 0;
double avgGrade = 0 ;
double grade;
double total = 0;
System.out.println("Please input the grade");
grade = keyboard.nextDouble();
while(true){
System.out.println("Please input the grade");
grade= keyboard.nextDouble();
count = count + 1;
if (grade < 0) break;
total += grade;
avgGrade = total/count;
}
System.out.println ("Sum is " +total);
System.out.printf("The average of the %.0f grades are %.2f " ,count ,avgGrade);
}
}
Output:
Please input the grade
100
Please input the grade
50
Please input the grade
-9
Sum is 50.0
The average of the 2 grades are 50.00
Sum should have been 150 and average 75.
The problem is that you are reading a grade from the user before the while loop begins and you are ignoring this value afterwards.
You should remove those 2 lines and things will work as expected. I commented those lines in the snippet below to explicitely show you the problem.
public static void avgGrade() {
Scanner keyboard = new Scanner(System.in);
double count = 0;
double avgGrade = 0;
double grade;
double total = 0;
// System.out.println("Please input the grade");
// grade = keyboard.nextDouble();
while(true){
System.out.println("Please input the grade");
grade = keyboard.nextDouble();
count = count + 1;
if (grade < 0) break;
total += grade;
avgGrade = total/count;
}
System.out.println ("Sum is " +total);
System.out.printf("The average of the %.0f grades are %.2f " ,count ,avgGrade);
}
As a side note, you should always try to minimize the scope of each of your variable. Here, the grade variable is only use inside the while loop so you can directly write double grade = keyboard.nextDouble(); and remove the declaration in the beginning of the method.
You are not adding the first grade which you are accepting outside of the while loop to the total.
Also there is no point in incrementing the count, if the grade is not acceptable, so increment your count only after the grade check.
You can rewrite your while block something like
while (true) {
System.out.println("Please input the grade");
grade = keyboard.nextDouble();
if (grade < 0)
break;
count = count + 1;
total += grade;
}
avgGrade = total / count;
System.out.println("Sum is " + total);
System.out.printf("The average of the %.0f grades are %.2f ", count,
avgGrade);
}
Thanks guys. Here is the final code
/**
* This program will calculate grade average of user input
*
* Date: 10/2/2015
*/
import java.util.Scanner;
public class GradeAVG {
public static void main(String[] args) {
avgGrade()
}
public static void avgGrade()
{
Scanner keyboard = new Scanner (System.in);
double count = 0;
double avgGrade = 0 ;
double total = 0;
while(true){
System.out.println("Please input the grade");
double grade= keyboard.nextDouble();
if (grade < 0) break;
count = count + 1;
total += grade;
avgGrade = total/count;
}
System.out.println ("Sum is " +total);
System.out.printf("The average of the %.0f grades are %.2f " ,count ,avgGrade);
}
}
Several problems:
First, you do two assignments into grade before first reading from it (first one before the while loop and second inside the while loop), so the first input will be ignored entirely
Second, you increment the count variable before checking whether to break the while loop, so you end up with count higher by 1 than should be
Third, the average is computed inside the loop and will not be recalculated in the last (partial) iteration
The program will go like this:
input: 100, count: 0, total: 0, avg: 0
input was ignored
input: 50, count: 1, total: 50, avg: 50
input: -9, count: 2, total: 50, avg: 50
loop exit, but incremented count before; did not recalculate avg