public class Student
2: import java.util.Arrays;
4: /**
5: * A class to hold some very basic information about a student.
6: * Added an array of grades (assignment grades) to replace the one percentage
7: * grade of earlier versions.
8: *
9: * @author Mark Young (A00000000)
10: * @version 3.1 (2017-11-06)
11: */
12: public class Student {
14: /** The student's A-Number */
15: public final String A_NUMBER;
16: /** The student's name */
17: private String name;
18: /** The student's grade (as a percentage) */
19: private int[] asgnGrades;
21: // Class information -- common to all Students //
23: /** The number for the next Student created */
24: private static int nextANumber = 1;
26: /** Maximum possible percentage grade */
27: public static final int MAX_GRADE = 100;
28: /** Minimum possible percentage grade */
29: public static final int MIN_GRADE = 0;
30: /** Number of assignments in course */
31: public static final int NUM_ASGN = 8;
32: /** Number of dropped assignment grades */
33: public static final int NUM_DROPS = 2;
34: /** Special value to represent a non-existent grade */
35: public static final int INVALID_GRADE = -1;
37: /**
38: * Create a Student object.
39: *
40: * @param name the requested name
41: */
42: public Student(String name) {
43: // assign next A-Number to this Student
44: this.A_NUMBER = String.format("A%08d", nextANumber);
45: ++nextANumber;
47: // set personal data
48: this.name = name;
49: this.asgnGrades = new int[NUM_ASGN];
50: // array starts off all zeroes, which is what we want,
51: // so no need to set each asgnGrades[i]
52: }
54: /**
55: * Get the value of A_NUMBER
56: *
57: * @return the value of A_NUMBER
58: */
59: public String getANumber() {
60: return A_NUMBER;
61: }
63: /**
64: * Get the value of name
65: *
66: * @return the value of name
67: */
68: public String getName() {
69: return name;
70: }
72: /**
73: * Get student's grade on a particular assignment.
74: *
75: * @param a the assignment requested
76: * @return the grade on the requested assignment
77: * OR INVALID_GRADE if there is no such assignment
78: */
79: public int getAsgnGrade(int a) {
80: if (isValidAssignment(a)) {
81: return asgnGrades[a - 1];
82: } else {
83: return INVALID_GRADE;
84: }
85: }
87: /**
88: * Get the student's percentage grade on assignments.
89: * Current version is based on average assignment grade,
90: * dropping the lowest grades.
91: *
92: * @return this Student's average assignment grade
93: */
94: public int getAsgnsGrade() {
95: int[] drops = getSmallest(asgnGrades, NUM_DROPS);
96: int sum = sumArray(asgnGrades) - sumArray(drops);
97: return (int)Math.round((double)sum / (NUM_ASGN - NUM_DROPS));
98: }
100: public int[] getAsgnGrades() {
101: return Arrays.copyOf(asgnGrades, NUM_ASGN);
102: }
104: /**
105: * Get the course grade for this student.
106: * Eventually this will be based on all grades,
107: * but currently it is based only on the assignments grade.
108: *
109: * @return this Student's percentage grade for the course
110: * @since 3.1
111: */
112: public int getGrade() {
113: return getAsgnsGrade();
114: }
116: /**
117: * get letter grade for this student
118: *
119: * @return the letter grade equivalent to this student's percentage grade
120: * @since 2.0
121: */
122: public String getLetterGrade() {
123: return Student.letterGradeFor(this.getGrade());
124: }
126: /**
127: * Set the value of name
128: *
129: * @param name new value of name
130: */
131: public void setName(String name) {
132: this.name = name;
133: }
135: /**
136: * Set the value of an assignment grade.
137: *
138: * @param a number of assignment this grade is for
139: * @param g new assignment grade (must be 0..100)
140: */
141: public void setAsgnGrade(int a, int g) {
142: if (isValidAssignment(a) && isValidGrade(g)) {
143: asgnGrades[a - 1] = g;
144: }
145: // otherwise fail without warning(!)
146: }
148: /**
149: * Print a brief summary of the student's data.
150: */
151: public void printRecord() {
152: System.out.println("\tNumber: " + A_NUMBER);
153: System.out.println("\tName: " + name);
154: System.out.println("\tGrade: " + getGrade());
155: System.out.println("\tLetter: " + this.getLetterGrade());
156: }
158: /**
159: * Create a String to represent this Student.
160: * This version uses their name and A-number.
161: *
162: * @return a String representing this Student
163: */
164: @Override
165: public String toString() {
166: return name + " (" + A_NUMBER + ")";
167: }
169: /**
170: * Return whether a given grade is in the valid range.
171: *
172: * @param g the grade to check for validity
173: * @return whether g is in the correct range.
174: * @since 2.0
175: */
176: public static boolean isValidGrade(int g) {
177: return (MIN_GRADE <= g && g <= MAX_GRADE);
178: }
180: /**
181: * Return whether a given number is a valid assignment number.
182: *
183: * @param a the number to test for validity
184: * @return whether a is in the correct range
185: * @since 3.0
186: */
187: public static boolean isValidAssignment(int a) {
188: return 1 <= a && a <= NUM_ASGN;
189: }
192: /**
193: * Return the letter grade corresponding to the given grade.
194: *
195: * @param g the percentage grade to be converted to a letter grade.
196: * @return the letter grade corresponding to g.
197: * @since 2.0
198: */
199: public static String letterGradeFor(int g) {
200: if (g < 50) {
201: return "F";
202: } else if (g < 60) {
203: return "D";
204: } else if (g < 63) {
205: return "C-";
206: } else if (g < 67) {
207: return "C";
208: } else if (g < 70) {
209: return "C+";
210: } else if (g < 73) {
211: return "B-";
212: } else if (g < 77) {
213: return "B";
214: } else if (g < 80) {
215: return "B+";
216: } else if (g < 85) {
217: return "A-";
218: } else if (g < 90) {
219: return "A";
220: } else {
221: return "A+";
222: }
223: }
225: /**
226: * Sum the elements of an array.
227: *
228: * @param arr the array to sum the elements of
229: * @return the sum of the elements of arr
230: */
231: private static int sumArray(int[] arr) {
232: int sum = 0;
233: for (int i = 0; i < arr.length; ++i) {
234: sum += arr[i];
235: }
236: return sum;
237: }
239: /**
240: * Return an array containing the lowest values from an array.
241: * Requires that n %le; arr.length.
242: *
243: * @param arr the array to find the lowest values in
244: * @param n the number of lowest values to find
245: * @return an array containing the n smallest values of arr
246: */
247: private static int[] getSmallest(int[] arr, int n) {
248: int[] copy = Arrays.copyOf(arr, arr.length);
249: Arrays.sort(copy);
250: return Arrays.copyOfRange(copy, 0, n);
251: }
253: }