1. Introduction

In this assignment, you are to implement a console application that supports simple grade book functionality. A phased implementation approach is recommended; refer to Appendix 2 for further details.

  1. The Application

Student marks are to be loaded from 3 arrays containing student ids, assignment marks and exam marks. Loading involves the creation of a Record instance from each triple (student id[i], assignment[i], exam[i]). These are to be stored in an array of type Record called book. The size of this array is to be the same size as the input arrays. During loading, the total and grade for each student is calculated. The code for loading is provided in Appendix 1.

The allocation of grades is follows:

Grade Range
HD 85-100
D 75-84
C 65-74
P 50-64
F 1-49
AF 0

 

This allocation is to be provided as a separate (private) method. In order to facilitate search, book is to be maintained in ascending order of student id. Sorting is to be done after loading, using the selection sort algorithm.

The application’s View class is to display and execute (using a switch statement) a menu with the following options:

  1. Display the record for a specified student
  2. Display records for all students with total marks within a specified range.
  3. Display the minimum, maximum and average total marks
  4. Exit the application

Refer to appendix 2 for one way of structuring the user interaction.

Note that:

  1. For 1 and 2, basic error checking is expected. For 1, an error message is to be displayed if the student id does not exist. For 2, an error message is to be displayed if a member of the range is < 0 or > 100 or if the second member of a range is less than the first member.
  2. For 2, the range is inclusive of the values specified and both members of a range can be equal.
  3. For 1, binary search is to be used
  4. For 2, the results are to be stored in an ArrayList for display

The application must conform to the class diagram of Figure 1.

Figure 1. Class Diagram

Note that in Figure 1, the visibility of class methods and attributes are designated as + (public) and – (private). Associations are annotated with a label (for readability) and multiplicity. The multiplicity captures the number of object instances that can be involved in the association. In this case, only two values apply – 1 and *, which means many.

 

  1. Submission

You are to submit a zipped folder containing

  • The four .java files that comprise your application. Alternatively, if you have used NetBeans, this can be replaced with a zipped project folder. Details of how to do this will be provided later in the unit.
  • Report.docx (this file contains a brief report that includes student name, student ID number, course name, course code and test results (screenshots/test cases with results to show that your application is working correctly))
  1. Marking Criteria

Criteria Marks Allocated
1 Functionality: Marks (2 marks)
Construction of objects as per spec /2
2 Functionality: View (3 marks)
Command loop implementation /2
Constructor implementation /1
3 Functionality: Record (2 marks)
Constructor, getters implementation /2
4 Functionality: GradeBook (13 marks)
Find record by id (0 if binary search not used) /3
Find records by range of marks /3
Find lowest mark /1
Find highest mark /1
Find average mark /1
Sort records (0 if selection sort not used) /3
Calculate grade /1
7 Coding Style (5 marks)
Program logic /1
Spacing and indentation conventions /1
Naming conventions /1
Comments /2
8 Report (5 marks)
Test results /4
Presentation(fonts, spaces, information, language) /1
Sub-Total /30
Penalties
Does not compile/run: 25-30 marks
Late submission : 5% (1 mark) / day or part of a day
Total /30

 

 

 

Appendix 1

The code for theGradeBook. loadFromTables() method (which is to be called from the GradeBook constructor) is as follows:

private void loadFromTables() {

String[] students = {

“S10″,”S20″,”S30″,”S40″,”S50”, “S60”,

“S08″,”S18″,”S28″,”S38″,”S48”, “S58”,

“S06″,”S16″,”S26″,”S36″,”S46”, “S56”,

};

int[] assignment = {

0, 10, 20, 30, 30, 40,

0, 10, 20, 30, 30, 40,

0, 10, 20, 30, 30, 40,

};

int[] exam = {

0, 39, 44, 44, 54, 59,

1, 40, 45, 45, 55, 60,

2, 41, 46, 46, 56, 58,

};

nrecords = students.length;

gradeBook = new Record[nrecords];

for (int i = 0; i < nrecords; i++ ) {

int t = assignment[i]+exam[i];

String g = calculateGrade( t );

Record r = new Record( students[i], assignment[i], exam[i], t, g );

gradeBook[i] = r;

}

}

 

Appendix 2

It is good practice to develop an application incrementally. The idea is that the work is broken up into phases, with each phase producing a working system. Furthermore, if a phase involves the provision of multiple functionalities, as in Phase 3 below, these should also be tackled incrementally. The advantage of this approach is that you have a series of working systems that you can demonstrate to the customer. In your case, it means that you can always submit a working system, albeit one perhaps with limited functionality. For this to work properly, you need to save copies of your working versions as you go. This way of doing things is such a good idea (especially for team development) that software support is readily available in the form of version control systems such as SVN, GIT, CVS etc. However, we don’t introduce you to version control until later in your course.

In terms of how you might phase this assignment, below is how I went about it, given that I was working from a class diagram. Arguably, it would be better to start with Phase 2 and have an initial application that produces output. I didn’t do this as Phase 1 is straightforward and much of it is needed for Phase 2 anyway.

Phase 1.

  1. Create all classes with members and dummy methods as per the class diagram. Where constructors set member variables via parameters, add code to do this. Leave void methods with an empty body. Where methods require a return value, just return a sensible type-consistent default value, as shown below for the GradeBook public methods:

public Record find( String sid ) {

return new Record ( “S01”, 0, 0, 0, “F” );

}

public int lowestMark() {

return 0;

}

public int highestMark() {

return 0;

}

public double averageMark() {

return 0.0;

}

public ArrayList<Record> find( int mark1,int mark2 ) {

ArrayList<Record> alr = new ArrayList<>();

alr.add( new Record ( “S01”, 0, 0, 0, “F” ) );

alr.add( new Record ( “S02”, 0, 0, 0, “F” ) );

return alr;

}

We could have returned null for the methods that return object references, but I chose to return something slightly more interesting. Bear in mind that if find(String sid) is unsuccessful, returning null is a good way to indicate failure and you will ultimately need to test for this. In the case of find(int mark1, int mark2), there are two sensible choices – either return null or return an empty list on failure. Also note that you will have to include any import statements that are needed.

  1. In the main() method, add the following code:

GradeBook gb = new GradeBook();

View v = new View( gb );

v.commandLoop();

 

Do not proceed to Phase 2 until this code compiles. You now have an application that compiles but when it runs, no output will be produced.

Phase 2.

Get the command loop working with the dummy methods. You will need to provide real getter methods for the Record class. You might find it helpful to write some private helper methods, e.g.

private String help() {

return

“The following commands are recognised\n”+

“\tDisplay this message > 0\n”+

“\tDisplay a specific student record: > 1 studentID\n”+

“\tDisplay records for all student records within a range > 2 mark1 mark2\n”+

“\tDisplay statistics (minimum, maximum and average marks)> 3\n”+

“\tExit the application > 9\n” ;

}

and perhaps display methods for commands 1,2 and 3.

When I did this with our dummy testing methods, the following output was generated:

run:

The following commands are recognised

Display this message > 0

Display a specific student record: > 1 studentID

Display records for all student records within a range > 2 mark1 mark2

Display statistics (minimum, maximum and average marks)> 3

Exit the application > 9

> 1 1

<S01,0,0,0,F>

> 2 50 50

<S01,0,0,0,F>

> 3

Lowest mark is 0

Highest mark is 0

Average mark is 0

> 4

Invalid command. The following commands are recognised

Display this message > 0

Display a specific student record: > 1 studentID

Display records for all student records within a range > 2 mark1 mark2

Display statistics (minimum, maximum and average marks)> 3

Exit the application > 9

> 9

BUILD SUCCESSFUL (total time: 1 minute 7 seconds)

Note I have displayed records very tersely; you will need to at least add member names. Also, the interaction is minimalist. You may prefer to display the menu before every command and explicitly prompt for all inputs – either style is fine.

Phase 3

We now need to

  1. populate the grade book with student records using the code provided
  2. change the relevant grade book methods to use this data rather than just returning dummy values as in Phase 2.

Note that

  1. we can do the changes one at a time, retaining dummy methods for the commands that we are yet to work on.

  2. generating statistics will be the same regardless of whether the records are in sorted order (they are to be sorted according to student id) so that is a good (and easy) place to start.

Phase 4

Test the application. Enter commands that will test edge cases. Also change the data to introduce additional edge cases. E.g. what will happen with 0 records? One record? Etc.

 

Related posts: