Due Tuesday, September 6 @ 8:00pm on Gradescope
The purpose of this homework is to give you practice programming with your first real “data structure”, and an important one in Java, the ArrayList
. You will also obtain practice writing and testing a class from scratch. In this homework, you will implement a simple gradebook for a course. Your gradebook will input a CSV file containing student information and assignment grades. The gradebook will consist, basically, of an ArrayList
of Students. Each student will be an instance of the Student class, but you will have to augment the initial Student class with a private instance variable that can hold an ArrayList
of grades. There are other, better, ways to store grades, but it will work for this assignment, the focus of which is on ArrayLists and their operations. You will also need to write the Grade
class.
Download a pre-prepared Eclipse Project hw3.zip
and import it into Eclipse using these instructions. You will make all of your changes inside of the java files in this project.
For this assignment you have 5 submissions. You should write your own testcases while you work so that you don’t waste submissions. After you have used your submissions, you may continue to submit, but your submission will be penalized 4 points for every extra submission. (So, your 6th submission receives a -4, your 7th submission a -8, etc.)
There are a variety of tasks for this homework.
Grade
ClassThe Grade class will represent and store information about a single grade. A grade has two components: a name (stored as a String, e.g., HW1) and the actual grade for that assignment (stored as an int). You will need to write a constructor for this class as well as a few methods, such as getters and setters.
Student
ClassYou need to write your own Student
class to store information about a student. Included with this assignment is a pre-existing Person
class. Since a student is-a person, you should use inheritance when creating the Student
class. A student is a person who also has an andrew ID, a major, and an ArrayList
of grades. You will also need to write a variety of other methods for Student
as needed. Beyond this, the details of the Student
class are not described in detail here; you will need to figure out on your own exactly what you need.
GradeBook
ClassYou will need to write the following methods in the GradeBook
class. With the exception of the constructor, most GradeBook
methods should be very short, as anything that involves an individual Student
should be a method in the Student
class, called on the appropriate Student
from the GradeBook.
public GradeBook(String filename)
A basic constructor that creates a Gradebook based on the contents of a file. In particular, you will need to decide how to incorporate the reading of the grades. A suggestion would be to read the file a line at a time, parse the line into tokens using split
and loop over the grade-name/grade-value pairs. You may assume that the file is well-formatted, i.e., each line contains a first name, last name, andrewID, and a number of grade-name/grade-value pairs. You will also have to decide how to get the grades into the ArrayList
of Grades that you will need to add to the Student class. I would suggest building a Student
with the names and id and then create a method called addGrade
inside Student
to add each grade to the appropriate instance variable of the Student object.
filename
— The file containing student grade information
private Student findStudent(String id)
This method is optional, but you will almost certainly want it to help you in building other methods. It returns the Student
corresponding to the andrew ID provided. If there is no student with that andrew ID, it returns null
.
public String[] getIds()
Produce an array of the andrew IDs of all students in the gradebook.
public String[] getIds(String major)
Searches the gradebook for all students having a specified major.
Parameters: major
— The major to search for
Returns: An array of the andrew IDs of all students with major
in the gradebook.
public boolean dropStudent(String id)
Drops the student with the given andrew ID from the gradebook.
Parameters: id
— The andrew ID of the student to drop.
Returns: true
if successful and false
otherwise.
public int getGrade(String id, String assignment)
Get the grade of the assignment
for the student with the given andrew ID.
Parameters:
id
— The andrew ID of a student
assignment
— An assignment name
Returns: The grade of student id
on assignment
. If the student or assignment could not be found, it returns -1.
public boolean addGrade(String id, String assignment, int grade)
Add a grade to a the student with the given andrew ID.
Parameters:
id
— The andrew ID of the student to add the grade to.
assignment
— The assignment name.
grade
— The student’s grade on the assignment.
Returns: true
if successful and false
otherwise.
public boolean changeGrade(String id, String assignment, int newGrade)
Change a grade of the student with the given andrew ID.
Parameters:
id
— The andrew ID of the student to change the grade of.
assignment
— The assignment name.
newGrade
— The new grade for the student on the assignment.
Returns: true
if successful and false
otherwise.
public ArrayList<Integer> getAssignmentScores(String assignment)
Retrieve all the student scores for a given assignment.
Parameters: assignment
— The assignment to get the scores for.
Returns: An ArrayList
containing all of the student scores for the assignment. If there are no scores (or the assignment does not exist), then return an ArrayList
containing no values.
public double getAverage(String id)
Calculate the current course average for the specified student. See the homework handout section entitled “Calculating the Course Average” for more details about how to compute this value.
Parameters: id
— The andrew ID of the student.
Returns: The student’s current course average, or -1 if the student could not be found or had no grades
public String getAverageLetter(String id)
Calculate the current course average for the specified student, but as a letter grade. (A, B, C, D, R). Apply the standard 90 and above is A, 80 to 90 is B, etc.
Parameters: id
— The andrew ID of the student.
Returns: The student’s letter grade or null
if the student could not be found or had no grades.
public String toString()
Needs to correctly return a properly formatted String that represents the contents (the roster) of the gradebook. Properly formatted, in this case, means following the same format convention of the input file. The method here is provided and you shouldn’t change it, but it relies on a functional toString
in Student
, which is not provided.
The input (and output) files that your program should be able to work with have a comma separated value (CSV) format. Each line the file contains the information for one contact, with each field of that contact separated by a comma. The fields are:
First Name, Last Name, Age, Major, andrew ID, Grade Pairs, ...
Each “grade pair” consists of the name of the grade (homework, quiz, etc.) followed by the actual grade for that assignment. To keep things simple, assume you have only 4 categories of grades, formatted as follows: homeworks (HWn), quizzes (Qn), midterm (M) and Final (F). Note that there is not a specific number of grades per student, it could vary.
The provided Eclipse project includes some sample files that you can use for testing. (Looking at them will also help you make sure you understand the file format.)
The gradebook in this assignment will calculate the grade using the following grade percentages:
40% Homework
15% Quizzes
20% Midterm Exam
25% Final Exam
The formula you will use to determine the current course average is, thus:
\(avg = \frac{HW_{avg} * 40 + Quiz_{avg} * 15 + Midterm * 20 + Final * 25}{40 + 15 + 20 + 25}\)
However, if some category of grade is missing entirely, then you need to remove it completely from the calculation. For example, if you have quiz, homework, and midterm scores available but no final exam, then you would use…
\(avg = \frac{HW_{avg} * 40 + Quiz_{avg} * 15 + Midterm * 20}{40 + 15 + 20}\)
Let’s consider a practical example:
Darrel,Haley,23,Biology,dhaley,Q1,100,HW1,95,Q2,85
Darrel has some quiz and homework scores, but no midterm or final exam scores. His homework average is 95 (because there’s only one homework). His quiz average is 92.5. Therefore, his current course average is:
\(avg = \frac{95 * 40 + 92.5 * 15}{40 + 15} = 94.3181818\overline{18}\)
The skeleton code contains a very simple program, GradeBookManager.java
, that you can use to interact with a GradeBook. It is provided in order to give you an idea of how your GradeBook class could be used by an interactive program. We hope you find it helpful.
There are multiple parts of the grading of this assignment:
For the first 90 points, your submission will be auto-graded on Gradescope.
For the next 5 points, your submission will be manually graded to check for good implementation methodologies. (Did you use a good approach to solving the problems?)
For the next 5 points, your submission will be manually graded to check for good testcases that you include in the main method. (Do you have 2-3 of your own testcases for each method, and do they all execute automatically?)
Your code will also be checked for style. The parts of style that can be checked automatically (things like spacing, indentation, the use of CamelCase, etc.) are automatically checked by the autograder. Other parts of style, such as choosing good variable names, will be checked manually. Autograded style guide violations can result in, at most, -10 points. Manually checked style guide violations can result in, at most, -5 points.
You will submit your program to Gradescope. Login to the system and you will see the homework. Once there, you need to submit a zip
file containing your code. Lucky for you, however, Eclipse can create this zip file for you. Check out these instructions for exporting. On Gradescope, you’ll submit that exported zip
file. On the page that follows your submission you will see your live score (out of 90). It may take up to a few minutes for your score to appear; during that time just hit refresh in your browser. If you receive a lower score than you expect, you can click on the score to see the feedback from the autograder.
You must follow the model of our testcases from previous assignments (meaning you print when you start, print the results (pass/fail) when you finish, etc.) Additionally, you must comment each testcase with a note describing what it tests.
You may only use the following Java libraries in this assignment:
java.io.FileNotFoundException;
java.io.FileReader
java.io.PrintWriter
java.util.ArrayList
java.util.Arrays
java.util.Scanner
If you have questions, please post to Piazza. The course staff, including the instructor, monitor and answer questions there.
When posting to Piazza, if you include any code make sure your question is posted privately to the course staff, and not to the entire class.
Do not change the names of any of the provided methods or files. You may, however, add additional methods as needed.
After you submit to Gradescope, make sure you check your score. If you aren’t sure how to do this, then ask.
There is no partial credit on Gradescope testcases. Your Gradescope score is your Gradescope score.
Read the last bullet point again. Seriously, we won’t go back later and increase your Gradescope score for any reason. Even if you worked really hard and it was only a minor error…
You can submit to Gradescope multiple times. So, after you submit you should check your score. If it isn’t a 90 you can keep working until it is.
Don’t forget to make sure your code conforms to the style guide. We’ll be taking a look at that!
The style guide has a bunch of small rules with regards to indentation and spacing that are hard to follow perfectly. Luckily, Eclipse can handle it for you! Go to Source -> Format
in Eclipse and watch all of your spacing and indentation problems get fixed automatically. (You should do this before every submission.)
Don’t forget to write your own testcases! You are unlikely to succeed if you do not. (Remember, you are limited on submissions.)