0

I am working on a student scores application that accepts the last name, first name and score for one or more students and stores the results in an array. Then it prints the students and their scores in alphabetical order by last name. We do not know how many students there are, but there will be fewer than 100.

We have to display the class average at the end of the student information and display a message after each student whose grade is more than 10 points below the class average.

My first issue is that I have created a do/while loop to ask if the user would like to enter another but it will not work!?!?

Second, I can not figure out how to display the "10 points below" message on individual students.

public class Student implements Comparable
{
    String firstName;
    String lastName;
    int score; 

    //stores last name, first name and score for each student
    public Student(String lastName,String firstName,int score)
    {
        this.lastName = lastName;
        this.firstName = firstName;
        this.score = score;    
    }
    //implement the comparable interface so students can be sorted by name
    public int compareTo(Object o)
    {
        Student otherStudent = (Student)o;

        if(otherStudent.lastName.equals(lastName))
            {
            return firstName.compareToIgnoreCase(otherStudent.firstName);
            }
        else
            {
            return lastName.compareToIgnoreCase(otherStudent.lastName);
            }
    }
    public String toString()
    {
        return lastName + ", " + firstName + ": " + score; 
    }
}

import java.util.Scanner;
import java.util.Arrays;

public class StudentApp
{
    static Scanner sc = new Scanner(System.in);

    public static void main(String [] args)
    {
        Student [] studentArray;
        String lastName;
        String firstName;
        int score = 0;
        double average = 0;


        System.out.println("Welcome to the Student Scores Application.");
        System.out.println();

        do{

            //code that uses variable to specify the array length
        int nStudent = 100;  //array size not set unit run time
        studentArray = new Student[nStudent];

            for (int i=0; i<nStudent; i++)
            {
            System.out.println();

            lastName = Validator.getRequiredString(sc, 
                           "Student " + (i+1) +  " last name: ");
            firstName = Validator.getRequiredString(sc, 
                           "Student " +  " first name: ");               
            score = Validator.getInt(sc, 
                         "Student " + " score: ",
                        -1, 101);

            studentArray[i] = new Student(lastName, firstName, score);

            double sum = 0.0;
            sum += score;
            average = sum/nStudent;
            }
        }while (getAnotherStudent());

        Arrays.sort(studentArray);

        System.out.println();

        for (Student aStudent: studentArray)
        {
            System.out.println(aStudent);
            if (score<= (average-10))
            {
                System.out.println ("Score 10 points under average");
            }
        }
        System.out.println("Student Average:" +average);
    }
    public static boolean getAnotherStudent()
    {
        System.out.print("Another student? (y/n): " );
        String choice = sc.next();
        if (choice.equalsIgnoreCase("Y"))
            return true;
        else
            return false;
    }
}

3 Answers 3

2

There are a few problems here:

  • Every time through the do...while, you reinstantiate studentArray and sum. This means that all of your previously iterated over data is nuked when getAnotherStudent() is true - you want to instantiate the array and sum only once.
  • You don't stop if you have more than 100 students. You need an ending condition around nStudent as well in your loop.
  • You should make a few adjustments to getAnotherStudent() so that you can block on data, and wait when valid data is input - by using a loop:

     public static boolean getAnotherStudent() {
         Scanner sc = new Scanner(System.in);
         System.out.print("Another student? (y/n): " );
         if (sc.hasNext()) {  
             String choice = sc.next();
             // blocks here - ignores all input that isn't "y" or "n"
             while(!((choice.equalsIgnoreCase("Y") || choice.equalsIgnoreCase("N")))) {
                 if (choice.equalsIgnoreCase("Y")) {
                     return true;
                 }
                 System.out.print("Another student? (y/n): " );
                 choice = sc.next();
             }
          }
          return false; // obligatory
    
Sign up to request clarification or add additional context in comments.

2 Comments

Your blocking code sits in the loop when the user enters 'n'. It works correctly if you change your while loop to an || and move your if outside the loop.
I'm surprised I missed that. Thanks @Glitch.
1

Your code is close there are just a couple of problems. The reason why your do while loop is not working is that you have a for loop inside of it. This means that you will ask for 100 students before you ask if they want to add another one. Your sum is being created inside this loop so it will be reset each time.

Finally you do not know how many Students will be added but your code assumes there will be 100 Students. This means you cannot use the for each loop to go through the array as some could be null. Just use a regular for loop going up to the last index of a student you added. Here are the changes:

    Student[] student = new Student[nStudent]; 
    int studentCount = 0; //declear the counter outside the loop
    double sum = 0.0; //declear the sum outside the loop
    do {
        System.out.println();
        lastName = Validator.getRequiredString(sc, 
                       "Student " + (i+1) +  " last name: ");
        firstName = Validator.getRequiredString(sc, 
                       "Student " +  " first name: ");          
        score = Validator.getInt(sc, 
                     "Student " + " score: ",
                    -1, 101);

        student[studentCount] = new Student(lastName, firstName, score); 

        sum += score; //increase the sum

        studentCount++; //increment the counter

    } while (studentCount < nStudent && getAnotherStudent()); //stop if the user says 'n' or we hit the maximum ammount
    average = sum / studentCount; //work out the average outside the loop

    System.out.println();

    for (int i= 0; i< studentCount; i++ ) {
        System.out.println(aStudent);
        if (score <= (average - 10)) {
            System.out.println("Score 10 points under average");
        }
    }
    System.out.println("Student Average:" + average);
}

2 Comments

If the assignment calls for an array, there shall be no deviating from that. Remedy that issue.
Changed the ArrayList to an array and the end for each to a normal for loop because of the change.
-1

Your getAnotherStudent() method should read:

System.out.print("Another student? (y/n): " );
if (sc.hasNext()) {   // blocks until user entered something     
    String choice = sc.next();
            if (choice.equalsIgnoreCase("Y"))
                return true;
            else
                return false;
} else {
    // won't come here
    return false;
}

3 Comments

It waits until the user enters something, but it's bad design to abort when I enter "m" instead of "n" as was specified.
@Makoto Instead of downvoting, you could have edited the answer to restrict the acceptance of user input if you thing that's a good idea. However, I prefer an application that does not keep bugging me because I didn't type EXACTLY what it expected rather than just using some default value when that happens...
I'm not editing your answer. If you feel like it's fine the way it is, then you can disregard whoever downvoted you. I just feel strongly about usability and design; if I want to cancel by typing "n", it should only really respond to "n" and not "6". But again, if you're comfortable with it, don't worry about it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.