public class Student implements Comparable
1: package comparators;
3: import java.util.Arrays;
4: import java.util.Comparator;
6: /**
7: * A class to hold some very basic information about a student.
8: * Sorts "naturally" by name. But also has Comparators to allow sorting by
9: * grade (highest to lowest) and A-number.
10: *
11: * @author Mark Young (A00000000)
12: */
13: public class Student implements Comparable<Student> {
15: // ---------- Comparators available ------------------------------- //
16: public static final Comparator<Student> BY_NAME
17: = (one, other) -> String.CASE_INSENSITIVE_ORDER
18: .compare(one.getName(), other.getName());
19: public static final Comparator<Student> BY_GRADE
20: = (one, other) -> Integer.compare(other.getAverage(), one.getAverage());
21: public static final Comparator<Student> BY_ANUMBER
22: = (one, other) -> one.A_NUMBER.compareTo(other.A_NUMBER);
24: // ---------- Instance variables (and constants) ------------------ //
26: /** The student's A-Number */
27: public final String A_NUMBER;
28: /** The student's name */
29: private String name;
30: /** The student's grades (as percentages) */
31: private int[] asgnGrades;
34: // ---------- Class variables (and constants) --------------------- //
36: /** The number of student objects so far */
37: private static int numberOfStudents = 0;
38: /** Number of assignments graded so far */
39: private static int asgnsGraded = 0;
41: /** Total number of assignments */
42: public static final int NUM_ASGN = 8;
43: /** Maximum possible percentage grade */
44: public static final int MAX_GRADE = 100;
45: /** Minimum possible percentage grade */
46: public static final int MIN_GRADE = 0;
49: // ---------- Constructors ---------------------------------------- //
51: /**
52: * Create a Student object.
53: *
54: * @param initialName the requested name
55: */
56: public Student(String initialName) {
57: // count this student we're creating
58: ++numberOfStudents;
60: // assign next A-Number to this Student
61: A_NUMBER = String.format("A%08d", numberOfStudents);
63: // set personal data
64: name = initialName;
66: // set academic data
67: asgnGrades = new int[NUM_ASGN];
68: }
71: // ---------- Getters --------------------------------------------- //
73: /**
74: * Get the value of A_NUMBER
75: *
76: * @return the value of A_NUMBER
77: */
78: public String getANumber() {
79: return A_NUMBER;
80: }
82: /**
83: * Get the value of name
84: *
85: * @return the value of name
86: */
87: public String getName() {
88: return this.name;
89: }
91: /**
92: * Get the assignment grades
93: *
94: * @return the array of graded assignment scores
95: */
96: public int[] getAsgnGrades() {
97: return Arrays.copyOf(asgnGrades, asgnsGraded);
98: }
100: /**
101: * Get one assignment grade
102: *
103: * @return the grade for the given assignment, or zero if it doesn't exist
104: */
105: public int getAsgnGrade(int asgnNum) {
106: // if it's a valid assignment number AND it's been released
107: if (isValidAsgnNum(asgnNum) && asgnNum <= asgnsGraded) {
108: return asgnGrades[asgnNum - 1];
109: } else {
110: return 0;
111: }
112: }
114: /**
115: * get letter grade for this student
116: *
117: * @return the letter grade equivalent to this student's percentage grade
118: */
119: public String getLetterGrade() {
120: return letterGradeFor(getAverage());
121: }
123: /**
124: * Calculate and return this student's average assignment grade.
125: *
126: * @return the rounded average of this student's graded assignments
127: * or 0 if no assignments have been graded.
128: */
129: public int getAverage() {
130: int sum = 0;
131: for (int i = 0; i < asgnsGraded; ++i) {
132: sum += asgnGrades[i];
133: }
134: if (asgnsGraded == 0) {
135: return 0;
136: } else {
137: return (int)Math.round((double)sum / (double)asgnsGraded);
138: }
139: }
141: /**
142: * Get the student's grade on a single assignment.
143: * Note: assignments are numbered starting at 1.
144: *
145: * @param asgnNum the number of an assignment (1 .. NUM_ASGN)
146: * @return this student's grade on that assignment
147: */
148: public int getGrade(int asgnNum) {
149: if (isValidAsgnNum(asgnNum)) {
150: return asgnGrades[asgnNum - 1];
151: }
152: return 0;
153: }
156: // ---------- Setters --------------------------------------------- //
158: /**
159: * Set the value of name
160: *
161: * @param newName new value of name
162: */
163: public void setName(String newName) {
164: this.name = newName;
165: }
167: /**
168: * Set the assignment grades
169: *
170: * @param newGrades array with suitable grades
171: */
172: public void setAsgnGrades(int[] newGrades) {
173: if (areValidGrades(newGrades)) {
174: asgnGrades = Arrays.copyOf(newGrades, NUM_ASGN);
175: }
176: }
178: /**
179: * Set one assignment's grade
180: *
181: * @param asgnNum the number of the assignment (1-based)
182: * @param newGrade the grade for that assignment
183: */
184: public void setAsgnGrade(int asgnNum, int newGrade) {
185: if (isValidAsgnNum(asgnNum) && isValidGrade(newGrade)) {
186: asgnGrades[asgnNum - 1] = newGrade;
187: }
188: }
191: // ---------- Other observer methods ------------------------------ //
193: /**
194: * Print a brief summary of the student's data.
195: */
196: public void printStudentRecord() {
197: System.out.println("\n\tNumber: " + this.A_NUMBER);
198: System.out.println("\tName: " + this.name);
199: System.out.println("\tGrade: " + this.getAverage());
200: System.out.println("\tLetter: " + this.getLetterGrade());
201: System.out.println();
202: }
204: /**
205: * Create a String to represent this Student.
206: * This version uses their name and A-number.
207: *
208: * @return a String representing this Student
209: */
210: @Override
211: public String toString() {
212: return this.name + " (" + this.A_NUMBER + ")";
213: }
215: /**
216: * Sort Students "naturally" by name.
217: *
218: * @param that the Student this Student is being compared to
219: * @return negative if this student has the earlier name; zero if they have
220: * the same name; and positive is this Student has the later name
221: */
222: @Override
223: public int compareTo(Student that) {
224: return BY_NAME.compare(this, that);
225: }
228: // ---------- Class methods --------------------------------------- //
230: /**
231: * Return whether a given grade is in the valid range.
232: *
233: * @param g the grade to check for validity
234: * @return whether g is in the correct range.
235: */
236: public static boolean isValidGrade(int g) {
237: return (MIN_GRADE <= g && g <= MAX_GRADE);
238: }
240: /**
241: * Return whether a list of grades is in the valid range.
242: *
243: * @param gg the list of grades to check for validity
244: * @return whether gg is of a suitable length with all values
245: * in the correct range.
246: */
247: public static boolean areValidGrades(int[] gg) {
248: if (gg.length > NUM_ASGN) {
249: return false;
250: }
251: for (int i = 0; i < gg.length; ++i) {
252: if (!isValidGrade(gg[i])) {
253: return false;
254: }
255: }
256: return true;
257: }
259: /**
260: * Return whether an assignment number is in the valid range
261: *
262: * @param asgnNum the supposed assignment number
263: * @return whether asgnNum is in the range 1..NUM_ASGN
264: */
265: public static boolean isValidAsgnNum(int asgnNum) {
266: return 1 <= asgnNum && asgnNum <= NUM_ASGN;
267: }
269: /**
270: * Return the letter grade corresponding to the given grade.
271: *
272: * @param g the percentage grade to be converted to a letter grade.
273: * @return the letter grade corresponding to g.
274: */
275: public static String letterGradeFor(int g) {
276: if (g < 50) {
277: return "F";
278: } else if (g < 60) {
279: return "D";
280: } else if (g < 70) {
281: return "C";
282: } else if (g < 80) {
283: return "B";
284: } else {
285: return "A";
286: }
287: }
289: /**
290: * Set the number of graded assignments.
291: *
292: * @param released the number of the latest assignment released
293: */
294: public static void releaseAssignment(int released) {
295: if (isValidAsgnNum(released)) {
296: asgnsGraded = released;
297: }
298: }
300: }