758 views
owned this note
<style>
h3 {
border-bottom: 1px solid #ccc;
}
section {
margin-bottom: 2rem;
padding: 0em 1em;
padding-bottom: 1em;
border-radius: 4px;
background-color: #f7f7f7;
border: 1px solid #ccc;
}
summary {
font-weight: bolder;
}
summary:hover {
text-decoration: underline;
}
.todo {
color: #ff00ff;
border: 2px dashed #ff00ff;
padding: 0em 1em;
border-radius: 5px;
//display: none; // UNCOMMENT TO HIDE TODOs
}
</style>
# Homework 1C-from-FP (Spring 2025)
**Due: Friday, February 7th at 11:59pm**
:::info
**Collaboration Policy:** _You may collaborate as much as you want on this assignment_ (this is more flexible than the normal course policy). The goal is to get everyone up to speed on Java. You are required to turn this in, but it will be weighted lightly in final grades. That said, we strongly encourage you to actively try writing these on your own while collaborating, as future assignments will assume you can handle these sorts of problems independently.
:::
## Learning Objectives
In this assignment, you will:
- Practice working with Java’s built-in lists
- Practice structuring code around access modifiers
- Practice using Java types to control the ability to perform certain computations
### Stencil Code and Assignment Setup
Using **[this GitHub Classroom link](https://classroom.github.com/a/1T_tXD7t)**, accept the assignment and create a repository for your code. **Be sure to follow the [Java Stencil setup guide](https://docs.cs200.io/s/java-stencil-setup-guide)** for instructions on how to do this.
This assignment requires that you have IntelliJ installed and set up for this course. For details on the setup process, please see the [IntelliJ Setup Guide](https://docs.cs200.io/s/intellij-guide). If you’re having trouble, the guide includes a [Common Bugs/FAQ](https://docs.cs200.io/s/intellij-guide#Troubleshooting) section which might help.
### Style Expectations
While you may have seen references to the course style guide, for this first assignment **we’ll only be expecting the following style requirements**:
- Method and variable names are in `camelCase`
- Class names are in `UpperCamelCase`
- Basic Javadocs for all methods and classes (look [here](https://docs.cs200.io/java-style-guide#Documentation-Comments) for examples)
## Problems
In the last assignment, we created a `GradeReport` class. Now, it’s time to set up the gradebook for an entire class, as well as the ability to manage (and update) grades. We also want to support `Faculty` teaching multiple courses.
:::warning
**Assignment prerequisites**: In order to complete this assignment, you must have already completed [HW1B](https://docs.cs200.io/s/PhMiOzBji). In this homework, we’ll be building on top of classes that we’ve created in the previous homeworks.
**Similar to how you started HW1b, you will need to copy your class implementations from previous assignments into your project for this one.**
:::
### :rotating_light: Super important notes :rotating_light:
For this assignment, you will be creating several classes with fields. To be consistent with our autograder, you must follow a few conventions when doing this (for just this assignment):
- **Naming**: Name your fields with **exactly** the same names as listed in this handout. Our autograder will try and access fields with these names--if you don't use them, there will be errors!
## More Courses
### Task 1
**Edit your `Faculty` class so that the field that stores what they are teaching is a `LinkedList` of `Course` rather than a single `Course`.**
:::info
<details><summary><b><i>Details</i></b></summary>
You’ll have to update the constructor and perhaps other methods that worked on the previous field type as well.
Reminder that to use this, you will need the following import statement at the top of your `Faculty.java`:
```java
import java.util.LinkedList;
```
If you need to check whether a specific_ `Course` _object is in a faculty member’s list of courses, use the_ `LinkedList` _method_ `contains` _which takes an object and returns a boolean.
:::
</details>
<br>
## Creating a Gradebook
### Task 2
**Add a `gradebook` field to the `Course` class. It should be of type `LinkedList<GradeReport>`.** This field should be initialized to an empty list within the `Course` constructor.
**Don’t forget to import `java.util.LinkedList `in `Course.java`!**
<br>
## Adding Grades
### Task 3
**Add a method named `storeGrade` to the `Course` class.**
The method should take in a `Student` and a valid grade (either `LetterGrade` or `SNCGrade` from assignment 1B). The method should result in updating the `Course`’s `gradebook` to include a `GradeReport` for the corresponding student. You may assume that the student doesn’t already have a grade in the gradebook.
<br>
## Looking up GradeReports
### Task 4
**Create a method `findGradeReport` in the `Course` class that takes the name of a student and returns the `GradeReport` of the named student in the course.**
The method should return `null` if the student is not in the course. Mark this method as `private` (replacing `public` with `private` at the start of the method header.)
<br>
## Updating Grades
### Task 5
**Add a method named `updateGrade` to the `Course` class.**
The method should take in the name of a student (String) and a valid grade. The method should result in the new grade being stored in the gradebook for the given student. If the student does not have a grade, throw a `RuntimeException` with the message `"no grade for student"`.
:::success
**_Hint_**: Think about how to use methods you’ve previously written as helpers.
:::
:::info
<details><summary><b><i>Note:</i> Exceptions in Java</b></summary>
Java has different kinds of exceptions for different kinds of errors.
For now, we will use a `RuntimeException` for any error related to the logic of the program or system being represented (as opposed to `IllegalArgumentException` which we use when an input is not from an expected set of values). The syntax for this is: `throw new RuntimeException(<insert error message>);`
:::
</details>
## Finding Students in a Gradebook
### Task 6
**Add a method called `gradeLookup` to the `Course` class.**
The method should take a `Faculty` or `TA` object and a student name as input.
- If `gradebook` has a `GradeReport` for the given student name, the method should return a `String` representation of the grade.
- If the given `Faculty` or `TA` is not teaching the course, throw a `RuntimeException` with the message `"permission denied"`.
- If no such grade is found, a `RuntimeException` with the message `"student <NAME> not found"` should be thrown (where `"<NAME>"` is replaced with the student name being searched for).
In cases where both exceptions would apply, throw the `permission denied` exception.
:::info
**Hint**: Think about how to reuse methods that you’ve already written.
:::
_Part of the point of the question is for you to think about how to take an argument that can be_ `Faculty` _or_ `TA`_, but not a general_ `Student`_. We’ve covered everything you need in order to do this._
:::danger
**_You may NOT use_ `instanceOf` for this task**. (It's okay if you haven't heard of this before.)
<details><summary>Why can't I use instanceof?</summary>
`instanceof` can often produce code that is hard to maintain in larger projects. In this assignment, we want to practice good OO design principles, which usually means avoiding `instanceof`.
</details>
:::
## Identifying Students in Trouble
### Task 7
**Add a method `reportsWithC` to the `Course` class.** The method should return a list of `GradeReport` from the course `gradebook` in which the grade is the letter `C`.
_The point of this question is for you to practice using good object-oriented code organization to check attributes of objects._ **_You should NOT use getters to do this_** _(by this, we mean that your code should not pull a grade out of a gradebook to compare it to “C”)._
:::info
<details><summary><b><i>Note:</i> Checking Equality</b></summary>
In order to write this, you will need to be able to check whether two grades are the same.
Lab 2 gave a quick introduction to writing `equals` methods, but IntelliJ can also generate `equals` methods for you automatically!
If you start typing `public boolean equals` in a class, IntelliJ will give you a popup that asks whether it should generate “equals and hashcode methods”. Click through doing that (just ignore or delete the generated `hashcode` method).
**Hint**: Here are the Equals methods for LetterGrade and SNCGrade.
**LetterGrade.java**:
```java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
LetterGrade that = (LetterGrade) o;
return this.grade == that.grade;
}
```
**SNCGrade.java**:
```java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
SNCGrade sncGrade = (SNCGrade) o;
return this.pass == sncGrade.pass && this.passDistinction == sncGrade.passDistinction;
}
```
:::
</details>
<br>
## Protecting Grade Information
### Task 8
Grade information is sensitive, and hence should be kept private. Other information may also be sensitive. **Mark all of the fields in `GradeReport`, `Student`, `Faculty`, and `Course` as `private`.** If this breaks some of your existing code, create additional methods as needed to restore your code to working.
:::success
<details><summary><b><i>Hint</i></b></summary>
Do this in stages: mark a couple of fields private and make sure your code will still run. Repeat until you’ve marked all of the fields. If you followed the “no getters” rule until now, your code should work without anything breaking.
:::
</details>
:::info
<details><summary><b><i>What is a <code>private</code> field?</i></b></summary>
You will learn about `private` fields (also called "access modifiers") in lab this week.
In a nutshell, marking a field `private` means that the field cannot simply be accessed from outside the class by writing `object.field`.
Instead, you have to provide a method in the field’s class that will perform the desired computation (you **should not** just hand the field out through a simple “getter” method, for those who already know that term).
:::
</details>
<br>
## Testing
:::info
<details><summary><b><i>Note:</i> Testing Guidelines</b></summary>
When writing your test suite, you should test only the methods we have asked you to write in this handout. Do NOT reference in your tests fields or methods that are not required by the assignment, or the autograder may fail.
:::
</details>
Put your testing in the file `Homework1CTest.java`. You will submit this file to the **Homework 1C (17/111/112/19): Implementation** assignment on Gradescope.
### Task 9
**Write a thorough set of tests for `gradeLookup`.**
:::info
<details><summary><b><i>Details</i></b></summary>
You should develop a set of tests that check the expected interactions among `storeGrade`, `updateGrade`, `gradeLookup`, and `reportsWithC`. What do we mean? One might expect that `reportsWithC` (for example) could return a different output after a call to `updateGrade`. Good test suites therefore test the interactions between methods when the changes made by one should affect (or not!) the output that comes from the other. We’re asking you to develop a set of such interaction tests for these four functions.
:::
</details>
:::info
<details><summary><b><i>Note:</i> Private Methods and Testing</b></summary>
**You cannot test** `private` **methods in** `Homework1CTest.java` (because the test class cannot “see” private methods). You may want to test that method before you make it private, but do not include tests for private methods in your `Homework1CTest.java `file.
**Pro Tip:** If you find that you need to set up the same courses, students, etc for multiple tests, you can write a single method to set up your data and tell JUnit to run it before each test method. Here’s an example:
public class Homework1CTest {
Course c1, c2;
@Before
public void setup() {
this.c1 = new Course("VISA", 100, 1)
this.c2 = new Course("HIST", 310, 1)
}
@Test
public void testDept() {
Assert.assertEquals(c1.department,"VISA");
}
}
We create the variables for data as fields outside the methods. The `@Before` annotation tells JUnit to run that method before running every test. This way, your tests can focus just on the conditions to check, and you can set up the data just one time. This also restores the values of c1, etc before each test, in case you have a test that needs to modify your data.
:::
</details>
## Handing In
Begin by cloning the GitHub repository found by clicking the above GitHub Classroom link. The following files should be in the `sol` directory. You can move the files you wrote in 1B into this directory.
- `Course.java `containing public class `Course`
- `Faculty.java` containing public class `Faculty`
- `Student.java` containing public class `Student`
- `Person.java` containing public abstract class `Person`
- `TA.java` containing public class `TA`
- `GradeReport.java` containing public class `GradeReport`
- `IGrade.java` containing public interface `IGrade`
- `Letter.java` containing public enum `Letter`
- `LetterGrade.java` containing public class `LetterGrade`
- `SNC.java` containing public enum `SNC`
- `SNCGrade.java` containing public class
- `Homework1CTest.java` containing public class `Homework1CTest`
- `TestRunner.java` containing public class `TestRunner`
- `AutograderCompatibility.java` containing public class `AutograderCompatibility`
After completing this assignment, you should be ready to turn in (at least) the following files to the **Homework 1C-17/111/112/19: Implementation** assignment on Gradescope (make sure to exclude the `AutograderCompatibility.java` file from your submission):
- `Course.java `containing public class `Course`
- `Faculty.java` containing public class `Faculty`
- `Student.java` containing public class `Student`
- `Person.java` containing public abstract class `Person`
- `TA.java` containing public class `TA`
- `GradeReport.java` containing public class `GradeReport`
- `IGrade.java` containing public interface `IGrade`
- `Letter.java` containing public enum `Letter`
- `LetterGrade.java` containing public class `LetterGrade`
- `SNC.java` containing public enum `SNC`
- `SNCGrade.java` containing public class `SNCGrade`
- `Homework1CTest.java` containing public class `Homework1CTest`
:::info
**_Note:_** You may also include other classes, interfaces, and abstract classes.
:::
Once you have handed in your homework, you should receive an email, more or less immediately, confirming that fact. If you don’t receive this email, try handing in again, or ask the TAs what went wrong.
:::info
<details><summary><b><i>Note:</i> Autograder Compatibility</b></summary>
There should be a class in the stencil code named `AutograderCompatibility`. Using this class is required to ensure that your submission is working correctly with the autograder. You will be penalized if your code does not work with the autograder.
If Gradescope gives you the message _“Could not run your code (0.0/0.0),"_ uncomment the main method of `AutograderCompatibility` and check that it compiles and runs. If the Gradescope autograder still doesn’t work, come to hours or post on Ed for help.
:::
</details>
## FAQ
**For examples of tests, see the** [**Homework 1A FAQ**](https://docs.cs200.io/s/BkCbhOCKq#FAQ)**. If you have other questions, feel free to post on Ed or come to hours.**
***
_Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS200 document by filling out our_ [_anonymous feedback form_](https://forms.gle/SiWG5qQ4myZ1HqTM9)_!_