Carnegie Mellon University Website Home Page
 
Spring 2018

15-121 Homework 3: Grade Book - Due 2/19 at midnight

Download and unzip hw3-code.zip, which contains the start of the Student.java and the GradeBook.java files, as well as the Person.java file that we worked on in lecture. The Student class inherits from the Person class from HW1, but will require additional fields. The GradeBook class is new for this assignment and replaces the array used in HW2's contact list with an ArrayList of Student. There is also a new data file, S18grades.txt to be used with this assignment. Of course, the grades (and, potentially, some other info!) are made up so don't take anything personally! You can even change your own grades as you see fit! You will also have to create a new class completely from scratch, called Grade.java.

Note: You will be graded in part on your coding style. Your code should be easy to read, well organized, and concise. You should avoid duplicate code.


Background: A Grade Book

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. 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.


The Data File format

The data file for this assignment consists of a student's first name, last name, nationality, age, major, and andrew id, followed by a number of "grade pairs" for that student. 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 (MT) and Final (F). See S18grades.txt to see what all this looks like.


The Grade Class

The Grade class will represent and store information about a single grade. A grade has three components: a name (stored as a String, e.g., HW1), the actual grade for that assignment (stored as an int), and a weight (stored as an double). You will need to write a constructor for this class as well as a few methods (most likely, you will need a method to get a grade's name and actual value, get the weight of this grade, and change an actual grade). To calculate the weight of a grade, you will need to be able to determine the weight of an assignment (stored as a double), given its "category" (as determined by the grade's name). As dictated by the course policy, Homeworks have weight 0.07, Quizzes have weight 0.015, the Midterm weight is 0.14, and the Final weight is 0.25. You may assume these weights are fixed.


The GradeBook Class

You 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.

GradeBook(String fileName)
This constructor needs to be modified to work with the given file format. 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 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 have to add to the Student class. I would suggest building a Student with the names and id and then create a method called addGrade to add each grade to the appropriate instance variable of the Student object. YMMV...

String toString()
Needs to correctly return a properly formatted (spaced) String that represents the contents (the roster) of the gradebook.

void printIndividualGrades(String id)
Prints all the grades, nicely formatted, that are associated with the student with andrew id id. Prints nothing if no entries match the specified andrew id.

void printGradesByMajor(String maj)
Prints all the grades, nicely formatted, that are associated with each student that is in major maj. Prints nothing if no entries match the specified major.

void removeStudent(String id)
Removes the entry for the student with andrew ID, id, from the roster, using the appropriate ArrayList method. If there is no such student, prints an appropriate error message.

void changeGrade(String id, String assignment, int newgrade)
If a student with andrew ID, id, exists, changes the grade associated with assignment to newgrade. Prints an appropriate error message if either the id or assignment cannot be found.

void addGradeToAll()
Prompts the user for a new assignment to add to all the students, then loops through all the students, asking the user for a grade for the new assignment. Updates each Student object by adding the new assignment name and grade to the ArrayList of Grades for that student.

void printCurrentGrade(String id)
Searches for the student with the specified andrew id and prints the current letter grade for that student, if found. If there is no such student, prints an appropriate error message. The current letter grade for a student can be determined by multiplying the actual grade times the weight for each assignment, summing all of these multiplications, and then dividing by the sum of all the weights. Then apply the standard 90 and above is A, 80 to 89 is B, etc.

double whatDoINeed(String id, char grade)
You're almost done! This one is a lot like printCurrentGrade() except once you calculate the student's current score, you need to see what they need to average over the rest of the course to get the desired grade. Of course, if there is no student with this id, it should (yet again) print an error message. The calculation is fairly straightforward: you need to determine a student's current score (similar to printCurrentGrade()), determine the total of the weights consumed to this point in the course (total), and how much weight is left (rest). Note that total + rest must equal 1. So if you have the student's current score (score) out of 100, and a target grade ("A" requires a minimum of 90, "B" a minimum of 80, and so on), what a student needs to make that target can be expressed by the following formula:
need = (target - score * total)/rest.

void updateDatabase(String filename)
Creates a file with name provided by filename and writes the contents of the gradebook to this file. This file must be readable by the GradeBook constructor!

Some of the methods you will write in the GradeBook class will require that you change/add methods in the Student class. Others may require a different getter or setter.

Of course, you will also need to test your methods by calling them from main.


Submitting Your Work

When you have completed this assignment and tested your code thoroughly, create a .zip file with your work (including the Grade.java, Student.java, Person.java, and GradeBook.java). Name the zip file "your-andrew-id".zip and upload it to the HW2 folder on Box.

Make sure to keep a copy of your work just in case something goes wrong!