--- tags: Homeworks-Summer21 --- # Homework 1: Classes ### Due: May 21, 2021 (Anywhere on Earth) ## Learning Objectives * Create a class hierarchy that makes proper use of interfaces (for variant types or contracts) * Develop a collection of examples and tests that exercise key behavioral requirements aspects of a problem * Write programs that can compile and run against a provided interface * Write programs that behave as expected based on a provided description or collection of test cases * Report errors with Exceptions ## Assignment Link Using this [github classroom link](https://classroom.github.com/a/MDq3vz6o), accept the assignment and clone on your machine. (see our [Github Guide](https://hackmd.io/@cs18-spring-2021/BkfI_Pky_), which is from the spring, so mentally replace all "spring"s with "summer") If this is your first time downloading an assignment for the course, check out our [First Time Setup Guide](https://hackmd.io/6K9NmQ0fSjOxH7AYeIYGnw?view). If you're having trouble with IntelliJ, check out our [IntelliJ Common Problems](https://hackmd.io/webHvA8yTCqGOAKXYgrI_A) handout. Please make sure to read [our gradescope submission guide](https://hackmd.io/jC-SEMn_RpiGqMH_EhsDMw) before handing in your assignment! ## How to Hand In <a name="handin"></a> In order to hand in your solutions to these problems, they must be stored in appropriately-named files with the appropriate package header in an appropriately-named directory. The source code files should comprise the `src` package, and your solution code files, the `sol` package. We mean that all your solution code should have a line at the top saying `package sol;` and they should be in the `hw01-classes/sol/` directory. For this assignment there is no `src` code, but in the future, it will have `package src;` and be in `[homework-name]/src/`. After completing this assignment, the following solution files should be in your `hw01-classes/sol/` directory: * `Course.java` containing `public class Course` * `Faculty.java` containing `public class Faculty` * `Student.java` containing `public class Student` * `GradeReport.java` containing `public class GradeReport` * `LetterGrade.java` containing `public class LetterGrade` * `SNCGrade.java` containing `public class SNCGrade` * `Homwork1TestSuite.java` containing `public class Homework1TestSuite` * you may also have other classes and interfaces To hand in your files, submit these files to the **Homework 1: Implementation** assignment on Gradescope. Once you have handed in your homework, you should receive an email, more or less immediately, confirming that fact. You may have noticed a class `AutograderCompatibility`. Using this class is not required, but might help you debug if Gradescope tells you “The autograder failed to execute correctly. Please ensure that your submission is valid. Contact your course staff for help in debugging this issue. Make sure to include a link to this page so that they can help you most effectively.” If Gradescope doesn't tell you "works with autograder", try uncommenting the main method of `AutugraderCompatibility` and check that it compiles and runs. ## Testing Please make sure to test your code! Testing and good code design make up a lot of your grade for this homework. Put your testing in a file named `Homework1TestSuite.java`. We are autograding your test suites by running it against a series of [chaffs](https://drive.google.com/uc?export=view&id=1Rr6jxELllMUV9dJKGTWmadtfOVKm6U-N#page=6) (bad implementations) of the solution to see if your testsuite catches the bugs in those implementations. You do not need to catch every chaff. Instead, we are looking to see if your tests are covering relevant areas of the code. The chaffs are labeled with what area of the code their bug is in, and we want to see that your tests are catching at least a few chaffs in most of these areas of the code. A chaff might have an incorrect arithmetic formula, return the wrong value in an `if` statement, make an assumption about inputs (such as an arbitrary string input only getting lowercase strings), and so on (this list isn't exhaustive). Our goal in using chaffs is to help you get better at developing good sets of tests for programs. You should submit `Homework1TestSuite.java` to the **Homework 1: Testing** assignment on Gradescope. See [our gradescope submission guide](https://hackmd.io/@cs18-spring-2021/HkESq1uJd) for an explanation on how we are grading your tests, and how you can use the Testing assignment on Gradescope to get a better understanding of the assignment. For this and all assignments, you should test *all* of the **methods** that we have asked you to write. This includes testing all `Exception`s mentioned in the problem statements (For this assignment, you do not have to include test cases for any exceptions that are thrown in the constructor of a class)! For more information on testing, see the [FAQ section of the handout](#FAQ). **Note:** 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 wheat and chaff autograder may fail. ## The Hunt Begins... :::spoiler Optional theme material After a long journey on the S.S.N.C, you finally step foot on Rhode Island's firm soil. As you step through the cold New England night, a scrap of parchment flutters through the breeze to your feet. You pick it up and read its contents aloud. *My name, dear reader, you should already know* *A bear lamped in blue, left not long ago* *If treasure you seek* *In grades you should peek* *At the last will and testament of Blueno* You heed the advice of the mysterious message and continue onwards towards Brown. What secrets lay hidden beneath Brown's unique grading system? ::: ## Problem Setup A university manages information about courses, faculty, students, and grades. A faculty member is only allowed to issue grades to students in a course that they are teaching. Grades can also take different forms, such as S/NC grades versus letter grades. In this assignment, you'll practice working with classes and interfaces to capture these concepts. **Note:** The handout guides you through developing the code in stages. You will turn in one set of files with your cumulative work on all tasks. You do *not* need to maintain versions of your code from each task separately. **Note:** You will see several study questions in the handout. You are not required to submit answers to these, but they are worth thinking through as a check on how well you understand the material conceptually (in addition to programming with it). We're happy to discuss the study questions on Ed, in office hours, etc. ## Courses Start by creating a class named `Course` with fields for the `department` (a string like "CSCI"), `courseNumber` (integer like 180), and number of `credits` the course gives (a double that should be one of .5, 1, or 1.5). **Task:** Create the `Course` class with a constructor that takes all three fields as inputs. Within the constructor, check whether the provided number of credits is one of the three allowed values. If it is not, use the following statement to raise an error message (errors in Java are called *Exceptions*; throwing one will stop your program): ```=java throw new IllegalArgumentException("Invalid credits"); ``` Since 1-credit courses are the default, we can reduce the chance of errors by allowing someone to omit the credits and having a constructor set the default value. In Java, a class can have multiple constructors (they need different numbers or types of arguments). This is called *constructor overloading*. **Task:** Add a second constructor that takes only the department and course number as inputs, setting the credits to 1 (by default). In Java, it helps for each object to have a string-based representation that we can use to print out the object in a readable form. These printable representations are defined in methods named `toString`. **Task:** Write a method called `toString` in the `Course` class that takes no input and returns a `String`. The string representation of a class should combine the department and the course number. For example, a course in department ``"CSCI"`` with number `180` should yield the string `"CSCI180"`. You can concatenate strings with the `+` operator. You can also concatenate a `String` and a `int` with the `+` operator to create a new `String` in Java. ## Faculty and Students Now let's create some classes to represent `Faculty` and `Student`. **Task:** Create a `Faculty` class that has a field for the faculty member's name (a `String`), a field for their department (a `String`), and a field for the `Course` that they are currently teaching. (For this first assignment, we will assume that every faculty member is teaching exactly one course.) **Task:** Define a method `isTeaching` for faculty that takes a course and returns a boolean indicating whether the faculty member is teaching that course. (Use `==` to check for sameness for this and all other comparison questions this week.) **Task:** Create a `Student` class that has fields for the student's name and two courses that the student is taking (both of type `Course`). (For this assignment, we will assume that every student takes exactly two courses, and doesn't add or drop courses; we will relax this in homework 2.) The constructor should throw an `IllegalArgumentException` with the error message `"Invalid courses"` if the two classes are the same. **Task:** Define a method `isTaking` for students that takes a course and returns a boolean indicating whether this course is one of the two courses that the student is taking. **Study Question:** We could have represented courses within faculty and students as strings, such as "CSCI180". What's the advantage of using objects instead? Is there an advantage to using the strings? ## Grading Now, we want to represent grades using classes and objects. **Task:** Create a class called `GradeReport`that has three fields: `forStudent`, `forCourse` and `grade`. For now, let the grade be just an `int`. The constructor should take all three fields as inputs. (For now, we are only creating individual `GradeReport` objects; we will create sets of them on homework 2.) **Task:** Add a method called `giveGrade` to the `Faculty` class. This method should take as input the `Student` the faculty is giving the grade to, the `Course` that the grade is for, and a numeric grade. The method should return a `GradeReport` as long as the student is taking the given course and the Faculty is teaching the course. If either of these conditions fails, the method should throw a `RuntimeException` with the message `“Incorrect course”`. **Note:** 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). ## Enriching Grades Our initial setup has simple numeric grades, but in reality there are many forms of grades: numeric grades, S/NC grades, letter grades, written performance reports, and so on. We therefore want to relax our notion of grades to support more options. For this assignment, we will support two kinds of grades: letter grades (one of “A”, “B”, “C”, “NC”) and S/NC grades, which are captured with two booleans: one for whether the student passed, and another for whether the student has passed with distinction. The distinction boolean should only be true if the passed boolean is also true. **Task:** Define classes for `LetterGrade` and `SNCGrade`, with the components indicated above. The constructor for `LetterGrade` should take in a string `"A", "B", "C"`, or `"NC"` and store that string in its `grade` field. If the input string is any other string, you should throw an `IllegalArgumentException` with the message `“Invalid grade”`. To compare strings, we use a method on strings called `equals`, as follows: ```=java "Kathi".equals("kathi") // this will return false ``` The constructor for `SNCGrade` should take in a string with three possibilities: “SDIST”, “S”, or “NC”. You should use this string to set the fields `pass` and `passDistinction`. If the input string is any other string, you should throw an`IllegalArgumentException` with the message `“Invalid grade”`. **Task:** For each grade class, write a method `isPassing`, which takes no input and returns a boolean indicating whether the grade reflects the student having passed. For letter grades, any grade other than “NC” is a passing grade. **Task:** Write a `toString` method for each of `LetterGrade` and `SNCGrade`. In `SNCGrade`, the produced strings should be one of `"S"`, `"NC"`, or `"S (with distinction)"`. Currently, `GradeReport` and `giveGrade` expect a grade to be a number. Instead, we want a grade to be either a `LetterGrade` or an `SNCGrade` (dropping numbers as an option). :::warning *NOTE: we will cover interfaces/what you need for the next two tasks in lecture on Monday, 5/17*. ::: **Task:** Define an interface `IGrade` that requires an `isPassing` method that takes no inputs and returns a Boolean. **Task:** Modify your existing code such that each of `GradeReport` and `giveGrade` have the grade be either a `LetterGrade` or an `SNCGrade`. **Task:** Only professors are allowed to view students’ grades; furthermore, they can only view grades of students in their own courses. Add a method to the `Faculty` class called `viewGrade` that takes a `GradeReport` and returns a string. If the course in the `GradeReport` is taught by the faculty member, the method returns a string indicating the grade earned. You should throw a `RuntimeException` with the message `“Access denied”`, if the faculty is not teaching the course in the `GradeReport`. ## Getting started Complete the classes as described, starting with courses, then faculty, students, and then grades. Test the classes as you write them! ## FAQ **How do I use decimals in Java? What is a double?** A double is a data type that represents a decimal number. You can initialize a double similarly to an int, like so: ```java private double myDouble = 0.4; ``` **How do I test `Exceptions`?** The format for checking `Exceptions` is as follows: ```java= t.checkException(new <exception-type>("<error message of exception>"), <object on which the method is called>, "<name of method to call>", ...<arguments of method>); ``` In practice, it looks something like this: ```java= Faculty kathi; GradeReport report; ... t.checkException(new RuntimeException("Access denied"), kathi, "viewGrade", report); ``` Where `kathi.viewGrade(report)` throws a `RuntimeException` with the message "Access denied". If the method in question has more than one parameter, these would be added, separated by commas, at the end of the `checkException` call. **The tester isn't running certain test methods?** Make sure that *all test methods you want to run begin with `test`*. This is how the tester knows which methods to run. **When I run the tester, I get this scary message. Did my tests fail?** ![](https://i.imgur.com/pl5rjOK.png) No, this is just a warning from the testing library that we use. This message does not mean your tests passed or failed, but rather, it will print every time you execute the test class. Just ignore it. **When I run the tester, I get an even longer scary message and my tests failed. What happened?** ![](https://i.imgur.com/Ttz1yi1.png) Read this guide we just wrote [here](https://hackmd.io/@cs18-spring-2021/B13dwnndO) to fix this! **My wheats and chaffs are giving me unknown variable errors i.e.** ```java location: variable sncg1 of type SNCGrade src/main/java/sol/Homework1TestSuite.java:52: error: cannot find symbol t.checkExpect(this.sncg2.passed, true); ^ symbol: variable passed ``` Please check [this post](https://edstem.org/us/courses/5623/discussion/447938). Generally, this means you've included tests for methods or fields that weren't explicitly mentioned in the document and thus not in our solution. Please avoid such tests -- test using methods and fields we've explicitly included. ## The Hunt Continues... :::spoiler Optional theme material Whilst going through the grade reports, you find a loose sheet of paper hidden among the stack. ![](https://i.imgur.com/yu037pH.png) It dawns on you that Blueno may have left more than just their ghost behind. This might be the first clue to finding Blueno's lost treasure! It might be wise to save the above image. The subsequent clues may not be as easy to find... ::: --- *Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS18 document by filling out the (mostly) [anonymous feedback form](https://cs.brown.edu/courses/cs018/feedback)!*