Student-Marks-Capture-System / src / StudentMarking.java
StudentMarking.java
Raw
import java.util.Scanner;

/**
 * This class forms Java Assignment 1, 2021
 */
public class StudentMarking {

    /**
     * The message that the main menu must display
     */
    public final String MENU_TEMPLATE =
            "%nWelcome to the Student System. Please enter an option 0 to 3%n"
                    + "0. Exit%n"
                    + "1. Generate a student ID%n"
                    + "2. Capture marks for students%n"
                    + "3. List student IDs and average mark%n";

    public final String NOT_FOUND_TEMPLATE =
            "No student id of %s exists";


    /** Do NOT change the two templates ABOVE this comment.
     DO CHANGE the templates BELOW.
     */

    /**
     * Complete these templates which will be used throughout the program
     */

    public final String ENTER_MARK_TEMPLATE = "Please enter mark %d for student %s%n";
    public final String STUDENT_ID_TEMPLATE = "%S%S%02d%s%s";
    public final String NAME_RESPONSE_TEMPLATE =
            "You entered a given name of %s and a surname of %s%n" +
                    "Your studID is %s";
    public final String LOW_HIGH_TEMPLATE = "Student %s has a lowest mark of %d%n" +
            "A highest mark of %d%n";
    public final String AVG_MARKS_TEMPLATE =
            "Student ***%s*** has an average of %5.2f%n";
    public final String COLUMN_1_TEMPLATE = "%4s";
    public final String COLUMN_2_TEMPLATE = "%12s";
    public final String CHART_KEY_TEMPLATE = "Highest%11s%n%4d%12d%n";
    public final String REPORT_PER_STUD_TEMPLATE = "| Student ID %3d is %-5s | Average is %5.2f |%n";


    /**
     * Creates a student ID based on user input
     *
     * @param sc Scanner reading {@link System#in} re-used from {@link StudentMarking#main(String[])}
     * @return a studentID according to the pattern specified in {@link StudentMarking#STUDENT_ID_TEMPLATE}
     */
    public String generateStudId(Scanner sc) {
        /**
         *  Complete the generateStudId method which will allow a user to generate a student id
         */
        String name, studId;
        String firstName = "";
        String lastName = "";
        char midOfFirst;
        char midOfLast;
        char firstnameInitial;
        char lastnameInitial;
        int lastnameLength = 0;


        System.out.printf("Please enter your given name and surname (Enter 0 to return to main menu)%n");
        name = sc.nextLine();
        if (name.equals("0")){
            return null;
        }

        for (int x = 0; x < name.length(); x++) {
            if (name.charAt(x) == ' ') {
                firstName = name.substring(0, x);
                lastName = name.substring(x + 1);
                lastnameLength = lastName.length();
            }
        }
        firstnameInitial = firstName.charAt(0);
        lastnameInitial = lastName.charAt(0);
        midOfFirst = firstName.charAt(firstName.length() / 2);
        midOfLast = lastName.charAt(lastnameLength / 2);

        studId = String.format(STUDENT_ID_TEMPLATE,
                firstnameInitial, lastnameInitial, lastnameLength, midOfFirst, midOfLast);
        System.out.printf(NAME_RESPONSE_TEMPLATE, firstName, lastName, studId);

        return studId;
    }

    /**
     * Reads three marks (restricted to a floor and ceiling) for a student and returns their mean
     *
     * @param sc     Scanner reading {@link System#in} re-used from {@link StudentMarking#main(String[])}
     * @param studId a well-formed ID created by {@link StudentMarking#generateStudId(Scanner)}
     * @return the mean of the three marks entered for the student
     */
    public double captureMarks(Scanner sc, String studId) {
        /**
         * Complete the captureMarks method which will allow a user to input three mark for a chosen student
         * DO NOT change MAX_MARK and MIN_MARK
         */

        final int MAX_MARK = 100;
        final int MIN_MARK = 0;

        int[] marks = new int[3];
        int checkMark;
        int numOfMark = 0;
        int lowestMark;
        int highestMark;
        double total = 0;
        double avg;

        for (int x = 0; x < 3; x++) {
            System.out.printf(ENTER_MARK_TEMPLATE, (x + 1), studId);
            checkMark = sc.nextInt();
            sc.nextLine();
            if (checkMark >= MIN_MARK && checkMark <= MAX_MARK) {
                marks[numOfMark] = checkMark;
                total += checkMark;
                numOfMark++;
            } else
                x--;
        }

        for (int x = 0; x < 2; x++) {
            for (int y = 0; y < 2; y++) {
                if (marks[y] > marks[y + 1]) {
                    int temp = marks[y];
                    marks[y] = marks[y + 1];
                    marks[y + 1] = temp;
                }
            }
        }
        lowestMark = marks[0];
        highestMark = marks[2];

        System.out.printf(LOW_HIGH_TEMPLATE, studId, lowestMark, highestMark);

        avg = total / marks.length;

        System.out.printf(AVG_MARKS_TEMPLATE, studId, avg);


        System.out.printf("Would you like to print a bar chart? [y/n]%n");
        if (sc.nextLine().equals("y")) {
            printBarChart(studId, highestMark, lowestMark);
        }
        return avg;
    }

    /**
     * outputs a simple character-based vertical bar chart with 2 columns
     *
     * @param studId a well-formed ID created by {@link StudentMarking#generateStudId(Scanner)}
     * @param high   a student's highest mark
     * @param low    a student's lowest mark
     */
    public void printBarChart(String studId, int high, int low) {
        /**
         * The printBarChart method which will print a bar chart of the highest and lowest results of a student
         */
        System.out.printf("Student id statistics: %s%n", studId);
        final char COLUMN_CHAR = '*';
        int printHigh = high, printLow = low;

        while ( printHigh > printLow || printLow > 0){
            if (printHigh > printLow){
                System.out.printf(COLUMN_1_TEMPLATE, COLUMN_CHAR);
                printHigh--;
            }else if (printLow > 0){
                System.out.printf(COLUMN_1_TEMPLATE + COLUMN_2_TEMPLATE,COLUMN_CHAR, COLUMN_CHAR);
                printLow--;
                printHigh--;
            }
            System.out.printf("%n");
        }

        System.out.printf(CHART_KEY_TEMPLATE,"Lowest", high, low);
    }

    /**
     * Prints a specially formatted report, one line per student
     *
     * @param studList student IDs originally generated by {@link StudentMarking#generateStudId(Scanner)}
     * @param count    the total number of students in the system
     * @param avgArray mean (average) marks
     */
    public void reportPerStud(String[] studList,
                              int count,
                              double[] avgArray) {
        /**
         * The reportPerStud method which will print all student IDs and average marks
         */
        if (studList != null) {
            for (int x = 0; x < count; x++) {
                if (studList[x] != null) {
                    System.out.printf(REPORT_PER_STUD_TEMPLATE, (x + 1), studList[x], avgArray[x]);
                }
            }
        }
    }

    /**
     * The main menu
     */
    public void displayMenu() {
        /**
         * The displayMenu method to use the appropriate template with printf
         */
        System.out.printf(MENU_TEMPLATE);
    }

    /**
     * The controlling logic of the program. Creates and re-uses a {@link Scanner} that reads from {@link System#in}.
     *
     * @param args Command-line parameters (ignored)
     */
    public static void main(String[] args) {
        /**
         * Complete the main method to give the program its core
         */

        // DO NOT change sc, sm, EXIT_CODE, and MAX_STUDENTS
        Scanner sc = new Scanner(System.in);
        StudentMarking sm = new StudentMarking();
        final int EXIT_CODE = 0;
        final int MAX_STUDENTS = 5;


        String[] keepStudId = new String[MAX_STUDENTS];
        double[] avgArray = new double[MAX_STUDENTS];

        //  Build a loop around displaying the menu and reading then processing input
        int choice = 1;
        int numOfStud = 0;
        int whereIsIt = 0;
        String insertStudId;
        boolean found = false;

        while (choice != EXIT_CODE) {
            sm.displayMenu();
            choice = sc.nextInt();
            sc.nextLine();

            switch (choice) {

                case 1:
                    if (numOfStud < 5) {
                        keepStudId[numOfStud] = sm.generateStudId(sc);
                        numOfStud++;
                    }else {
                        System.out.printf("You cannot add any more students to the array");
                    }
                    break;

                case 2:
                    System.out.printf("Please enter the studId to capture their marks (Enter 0 to return to main menu)%n");
                    insertStudId = sc.nextLine();
                    if (insertStudId.equals("0")) {
                        break;
                    }
                    for (int y = 0; y < MAX_STUDENTS; y++) {
                        if (insertStudId.equals(keepStudId[y])) {
                            whereIsIt = y;
                            found = true;
                        }
                    }
                    if (found)
                        avgArray[whereIsIt] = sm.captureMarks(sc, insertStudId);
                    else
                        System.out.printf(sm.NOT_FOUND_TEMPLATE, insertStudId);
                    break;

                case 3:
                    sm.reportPerStud(keepStudId, numOfStud, avgArray);
                    break;

                default:
                    // Handle invalid main menu input
                    System.out.printf(
                            "You have entered an invalid option. Enter 0, 1, 2 or 3%n");
                    break;

                case EXIT_CODE:
                    System.out.printf("Goodbye%n");
                    break;
            }
        }

    }
}