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