<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 1A-from-OO (Spring 2025)
**Due: Tuesday, January 28 at 11:59pm EST**
:::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.
:::
**Need help?** Find us, as well as questions and answers from other students, on [EdStem](https://edstem.org/us/courses/69789/discussion). [Here’s our office hours schedule](https://brown-csci0200.github.io/calendars.html).
Hand In Instructions are at the end of the document.
### Learning Objectives
In this assignment, you will:
- Practice writing tests in Java
- Practice working with records in Java
- Practice maps and filters in Java
### Stencil Code and Assignment Setup
Using this [GitHub Classroom link](https://classroom.github.com/a/ggsFhmCx), accept the assignment and create a repository for your code. For step-by-step instructions on how to do this, see the **[Java Stencil setup guide](https://docs.cs200.io/s/java-stencil-setup-guide)**.
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#Common-BugsFAQ) section which might help.
:::info
<details><summary>Click here if you encounter errors about missing jar files when opening the stencil</summary>
<br>
If you receive errors about this, you may need to add both the hamcrest-core-1.3.jar and junit-4.13.2.jar files as dependencies to your IntelliJ project. If you’r not sure how to do this, check out the Adding Jars/Dependencies section of the IntelliJ Setup Guide.
</details>
:::
### 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)
### Relevant Documentation
Java is a large language with lots of optional code libraries. Going into the Java documentation for the kinds of questions arising in this homework will likely leave you more confused. The lecture materials should have everything you need. If not, ask us on Ed. We’ll get to using the documentation on the next assignment.
You will be using `FuncList` objects for this homework. Both `FuncList` and `IFuncList` (the interface) files are located in the src folder; the `IFuncList` has complete documentation for all relevant functions. Make note that you add to `FuncList` objects using the `link()` method, which adds objects to the _front_ of the `FuncList`!
</details>
***
### :warning: Super important notes :warning:
Since this is our first assignment, our autograder needs to be set up a bit differently than usual and has a few extra requirements. To be consistent with our autograder, you must follow a few conventions (just for hw1):
- **If we ask you to make fields in a class, make them `public`**: That is, if you were creating a field called `length`, you should declare it as `public int length`, similar to what we did in class.
- **Naming**: If the handout asks you to create a field or method, give it 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! You are free to use whatever names you want if you make extra helper methods or other fields--so long as it's for something we didn't specifically ask you to write.
:::success
**What to expect in HW1**: The handout, and HW1 as a whole, guides you through developing the code in multiple 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.
:::
## Email Utilities
In the starter code, you have been given the following Java record for representing an email:
```java
public record Email(String address, String message, boolean isRead) { }
```
The `EmailUtilities` class is constructed with a `FuncList` of `Email`s, which we treat as the inbox. `FuncList` is a special implementation of lists that we have provided: the contents of `FuncLists` cannot be modified and for-loops don’t work. You’ll have to program with these functionally, as we have done in lecture. You will find an `IFuncList` interface (and find `FuncList` implementation) in the `src` folder for this assignment.
### Overview
Later on in this section, you will be tasked with implementing the following methods in the `EmailUtilities` class. To practice testing, we're going to write examples and tests for them first. Here's a list of the methods we'll be using, to get you familiar with them (**do NOT start writing these yet!**):
- `getAllUnread` : returns a `FuncList` with all the emails from the inbox whose `isRead` field is `false`
- `markAsUnread` : returns a `FuncList` with the emails from the inbox, but with all of the `isRead` fields changed to `false`
- `unreadMessagesFrom` : takes in a sender’s email address and returns a `FuncList` of all of the unread emails in the inbox that are from that sender
- `messagesAbout` : takes in a text input and returns a `FuncList` of all of the emails in the inbox whose message contains that text
- `unreadFrom` : returns a `FuncList` of all of the usernames (without repetition) from which the inbox contains at least one unread email. A username is the portion of the e-mail address that comes before the ‘@’ sign, e.g. “`kfisler`” is the username for `kfisler@brown.edu`.
<br>
### Task 1-A
In `Homework1ATest.java`, we have given you an example `FuncList` (`testEmailList`) with which we have initialized an `EmailUtilities` object.
**Starting with `testGetAllUnread`, complete the Email utilities testing functions by filling up the `expectedResult` `FuncLists` with what you expect the result of each function call to be, following the descriptions above.** You can add the named emails (`e1`, `e2`, etc) to the expectedResults `FuncList`s, (using the `link` construct in `FuncList`) or construct new ones as necessary.
**Refer to the [Java Testing Guide](https://docs.cs200.io/java-testing-guide) for an overview of JUnit tests and assertion statements.**
:::warning
**Note: Your tests will not pass at this stage**: the point is to get you writing examples so that you can think through what each function is supposed to do before you write any code.
:::
When you’re done, **submit your testing file** _only_ to the **Homework 1A-15: Testing** Gradescope assignment. Ignore any outputs that are labeled Part 2 and Part 3 for now.
:::info
<details>
<summary>Autograder Details</summary>
If the Autograder looks like this:

That means the assertions in the test methods listed are incorrect. You should go back and check your understanding of what the expected values should be in your assertions.
Otherwise, if the autograder looks like this:

That means that you should go back and double-check that the assertion in the test method in question (in this case, `testGetAllUnread`) actually tests the method it is meant to test (in this case, `getAllUnread`). **For now, you can ignore any Chaff messages that start with Part 2 or Part 3.** We’ll get to those in later parts. Hence, if your output looks like:

you should be confident that your Part 1 tests look like they should, and you can move on to the next task.
:::warning
**_Note:_** This is a bit more guidance and structure on testing than you will get in the rest of the course. The point is to get used to the idea of actual and expected values in unit tests, so that you are well-prepared to use JUnit on future assignments!
:::
</details>
:::info
<details>
<summary>Details and Tips</summary>
Now, as we turn to the programming tasks, look at the methods you can use, whose documentation is listed in the `IFuncList` interface.
If you aren’t sure how to approach programming these, start by breaking down the problem statements into the kinds of operations listed in the notes: are you selecting elements, transforming (all or some) elements, getting distinct elements? Figure out which of these you need, which will tell you which `IFuncList` methods you need to use.
:::success
**_Useful built-ins:_** `filter` : This method takes in a predicate (a function that goes from objects to booleans) and is called on `FuncList` objects. If the predicate is true for an object in the `FuncList`, `filter` will include that object in its output. An example of a predicate is `i -> (i < 10)` where the `filter` method will take all objects in a `FuncList` that is less than 10.`map` : This method takes in a transform function that _transforms_ each value in the `FuncList` object. For example, passing in the transform function `i -> (i + 1)` will return a `FuncList` that adds 1 to each value in the `FuncList` that called `map`.Also remember that you can get all distinct values of a `FuncList` using `.distinct()`
:::
</details>
<br>
### Task 1-B
**Complete the `getAllUnread` function.**
The entire contents of this function should be a _single_ `return` statement (no other lines of code), using `map` and/or `filter` as necessary (found in `FuncList` class). Run the `testGetAllUnread` unit test and make sure it passes.
<br>
### Task 1-C
**Complete the `markAsUnread` function.**
The entire contents of this function should be a _single_ `return` statement, using `map` and/or `filter` as necessary. Run the `testMarkAsUnread` unit test and make sure it passes.
<br>
### Task 1-D
**Complete the `unreadMessagesFrom` function.**
The entire contents of this function should be a _single_ `return` statement, using `map` and/or `filter` as necessary. Run the `testUnreadMessagesFrom` unit test and make sure it passes. Remember to use `.equals()` for `String` equality!
<br>
### Task 1-E
**Complete the `messagesAbout` function.**
The entire contents of this function should be a _single_ `return` statement, using `map` and/or `filter` as necessary. To check if a `String` `s1` contains a substring `s2`, you can use the expression `s1.contains(s2)`. Run the `testMessagesAbout` unit test and make sure it passes.
<br>
### Task 1-F
**Complete the `unreadFrom` function**
The entire contents of this function should be a _single_ `return` statement, using `map` and/or `filter` as necessary. You should also make use of the `.distinct()` method, which can be called the same way `map` and `filter` are called, but without any inputs. This method removes duplicates from a `FuncList`. To split a string into two parts at a given character, you can use the `.split()` method:
```
String example = “Rice&Beans”;
System.out.println(example.split(“&”)[0]); // will be “Rice”
System.out.println(example.split(“&”)[1]); // will be “Beans”
```
**Run the `testUnreadFrom` unit test and make sure it passes.**
***
## Weather
A weather station needs to compute average rainfall over a period of time. Their data are available as a `FuncList` of integers. Negative numbers in the data are ignored as noise (ie. sensor malfunctions). One negative number, **-999**, is special: it may be used to indicate the end of the time period of interest (so all values that follow -999 are to be ignored, whether positive or negative). There is always at least one non-negative number before either -999 or the end of the `FuncList`.
The `testRainfall` unit test in `Homework1ATest.java` has an example of how the `getAverage` method can be used to verify that the answer for the `FuncList` `1, -2, 5, -999, 8` is 3 (the average of 1 and 5).
### Task 2-A
**Write more tests in the `testRainfall` method by creating new `Rainfall` objects and writing `Asserts` for calls to the `getAverage` method of those objects.**
To create data for these tests, create `FuncList` objects and `link()` items (refer to examples in the testing file). Thorough tests catch reasonable logic errors or functionality omissions that someone might make in writing this program.
When you’re done, **submit your testing file** _only_ to the **Homework 1A-15: Testing** Gradescope assignment, and check to see if you might be missing some tests. If you’re missing tests, you can read the output of the autograder to get some hints.
<br>
### Task 2-B
**Write the** `getAverage` **method in the** `Rainfall` **class as described above.**
:::success
**_Useful built-ins:_** `takeWhile` : just like `filter`, takes in a predicate (a function that goes from objects to booleans) and is called on `FuncList` objects. `takeWhile` takes elements in the `FuncList` until it encounters the first element where the predicate is false.
The ‘taken’ elements are returned as a new list. `FuncList.sum()` : a way of getting the sum of a `FuncList` of numbers (ints or doubles).Also remember that you can get the length of a `FuncList` using `.size()`
:::
This method does **not** need to be a single return statement, but, for reference, ours only has one expression before the return statement.
Run the `testRainfall` test and make sure it passes.
</details>
***
## Shopping Discounts
An online clothing store applies discounts during checkout. A shopping cart is a `FuncList` of the items being purchased. Each item has a name (a String like “shoes”) and a price (a real number like 12.50).
Each item is represented as follows:
public record Item(String name, double cost) { }
The `checkout` method in the `Cart` class adds up the costs of a `FuncList` of `Item`s and applies discounts as follows in the following order:
- If the cart contains at least $100 worth of shoes, take 20% off the cost of all shoes (match only items whose exact name is “shoes”).
- If the cart contains at least two hats, take $10 off the total of the cart after the shoes discount, if applicable (match only items whose exact name is “hat”).
Couple other things to keep in mind:
- If the total price of the cart is less than $0 after the discounts are applied, the cart total should be $0 (i.e. the cart total can never be less than $0).
- You can assume that all Items will have a cost greater than $0.
The `testCheckout` unit test in `Homework1ATest.java` has an example of just the first discount being applied because the cart contains $110 worth of shoes, but only one hat.
### Task 3-A
**Write more tests in the** `testCheckout` **method** by creating new `Cart` objects and writing `Asserts` for calls to the `checkout` method of those objects.
Annotate each with a commented description of what situation the test is designed to check. When you’re done, **submit your testing file** _only_ to the **Homework 1A-15: Testing** Gradescope assignment, and check to see if you might be missing some tests. If you’re missing tests, you can read the output of the autograder to get some hints.
### Task 3-B
**Write the** `checkout` **method in the** `Cart` **class as described above.**
To get the sum of a `FuncList` of doubles, you can use the `FuncList` `sum `method. You can and should use a combination of maps, filters, arithmetic expressions, and `if`-statements in this method. When you’re done, run the `testCheckout` test and make sure it passes.
***
## Hand In
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.
:::danger
**Your solution code files should be in the** `sol` **package.** This means that all your solution code should have a line at the top saying `package sol;` and they should be in the `sol/` directory.
:::
After completing this assignment, your `sol/` directory should **contain** the following files:
- `AutograderCompatibility.java` containing `public class AutograderCompatibility`
- `Cart.java` containing `public class Cart`
- `EmailUtilities.java` containing `public class EmailUtilities`
- `Homework1ATest.java` containing `public class Homework1ATest`
- `Rainfall.java` containing `public class Rainfall`
To hand in your homework, submit the following files to the **Homework 1A-15: Implementation** assignment on Gradescope (make sure to exclude the `AutograderCompatibility.java` files from your submission):
- `Cart.java` containing `public class Cart`
- `EmailUtilities.java` containing `public class EmailUtilities`
- `Rainfall.java` containing `public class Rainfall`
Also submit the final version of your `Homework1ATest.java` file to the **Homework 1A-15: Testing** assignment on Gradescope (that should be the only file in the submission).
Once you have handed in your homework, you should receive an email, more or less immediately, confirming your turn-in.
:::warning
<details>
<summary>
<b> Note on Autograder Compatability </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 _“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,"_ 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>
:::
***
_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/Myj4XSPx8cBJLxGt5)_!_