FAQ for Homework 7: PennPals
Helpful Links |
---|
HW7 Assignment Page / Instructions |
1200 Java Style Guide |
1200 Java Testing Guide |
Course Notes (Important to understand chapters 24-26 for this assignment) |
Setup
Can I import other parts of the Java standard libraries?
Sure. Do note that our reference solution only imports things from java.util
;
if you think you need to import things outside of that, you should ask us
beforehand to make sure you are on the right track.
Understanding the Problem
I’m confused about a certain command, where should I look?
There’s a table with a general description of what each command does under “Protocol” in the instructions. Start there. Afterwards, search for the command name on the instructions. For each command, we provide more information and a table describing error conditions.
I’m confused about a certain concept, where should I look?
We define every relevant concept on the instructions. Most of what you’ll need to understand the assignment can be found under “Task 1: understanding the problem” and “Protocol”.
I’m confused about a certain Error Condition, where should I look?
We specify every error condition in the
javadocs
for each method in ServerModel
. For further reference, the javadocs for
ErrorCode
are
here.
Model Design
What data structures should I use?
Consider the invariants that you need to maintain, and then choose the simplest
possible data-structure that maintains them. Get comfortable with the Javadocs
for each structure (see
Lists,
Sets,
Maps,
TreeMaps,
TreeSets,
and
LinkedLists).
Consider if the data is ordered vs. unordered, contains repeats or unique
values, is a simple collection or a mapping from one type of data to another.
According to the answer to those questions, choose a List
, Set
, or Map
.
You may also consider creating your own classes to group information rather than
use a data structure with only primitive types.
What should I use for the static / dynamic type of my data structures?
The dynamic types you can use in this assignment are TreeMap
, TreeSet
, and
LinkedList
.
The static type should be the most generalized collection that still works for the code. For example:
Set<ClassName> s = new TreeSet<>();
Do I need to handle invalid inputs?
Yes! Throw the appropriate error based on where you are in the program.
What should the getters in ServerModel
– that normally return a collection – return if there are no elements to be returned?
An empty collection.
One of my functions is very large, is that okay?
It is best to split large functions into helper functions. Not splitting up your code in this way will result in loss of style points. Remember to also comment the purpose of your helper functions. Try your best to avoid redundancy.
When you add elements to a list, do you add a clone of the object or a pointer to the original object?
Unless you’ve explicitly written code that makes a copy, a reference to the object will be passed to the list, so it will point to the same object on the heap.
Using the Collections
library
What are some useful methods of the Map
interface?
Besides the basic operations of
containsKey,
get,
and
put,
you might want to also look at
keySet
and
values.
However, make sure that you use the map appropriately. For example, if you
determine whether a key is present in the map by iterating over the keySet
,
instead of using containsKey
, you will lose points in your manual grade.
How do I iterate over a Set
or List
?
You can use the iterator or the “foreach” syntax to access each element in the collection. See Lecture 29 or Chapter 25.4.
How do I iterate over all of the entries in a Map
?
If you have a Map<A,B> m
, you can use the iterator with the entrySet
method.
For example,
for (Map.Entry<A, B> entry: m.entrySet()){
A k = entry.getKey();
B v = entry.getValue();
... // do something with k and v
}
How do I implement equals
and/or compareTo
for my custom class?
Try to keep in mind what field (or fields) would make two instances of your class identical. Things like IDs are generally good to include since they should be different for different instances.
IntelliJ has a helper for writing equals
if you go to Code > Generate… >
equals() and hashCode(). (We don’t teach hashing in this class, so feel free to
uncheck hashCode()
if you do this). The helper will prompt you for the fields
that will determine equality between two instances of the class.
For compareTo
, IntelliJ should generate the method header if your class
implements Comparable
. From there, you should figure out which fields make one
instance less than, greater than, or equal to another instance (similar to
equals
, but slightly more involved).
Running the Client
How do I run the client.jar
? When I try to open the client.jar
file I get a warning, what should I do?
If running locally, try right clicking on the file and selecting “Open” instead
of double clicking on it. If you are using Codio, check the README
. Make sure
you start the server before running the clients.
How do I open two clients at the same time?
On Codio, click “Run Chat Client” multiple times to get multiple client instances. If you’re doing local development, read the Running the Client Locally section of the writeup.
Errors & Exceptions
Why am I getting a ConcurrentModificationException
?
This happens when you try to change a data structure while still traversing it in a for-each loop. Look for cases where you are iterating through a collection and adding/removing from the same collection. We suggest you store what you need to remove in another collection and then iterate over that collection.
Why am I getting a compilation error when submitting?
If you get a compilation error in a file that you don’t recognize, such as
SubmissionInviteOnlyTest.java
, make sure that your zip file includes all of
the correct files.
I’m getting a duplicate class error when I submit?
Make sure you are submitting your files to Gradescope without any extra files. You should only be uploading these files:
src/main/java/org/cis120/ServerModel.java
src/test/java/org/cis120/ServerModelTest.java
- Any additional classes you made
How do I interpret the Response
Test Output?
If an assertEqual
comparing an expected and an actual response
object fails, it may be difficult to understand what happened.
Here’s an example of a test output:
response expected:<{User0=[:User1 JOIN java], User1=[:User1 JOIN java, :User1 NAMES java :@User0 User1]}> but was:<{User0=[:User1 JOIN java], User1=[:User1 NAMES java :@User0]}>
The test output displays who the Response
is sent to and what messages they
receive. The assert statement that produced the output shown above expected a
Response
would be sent to the users with nicknames “User0” and “User1”. The
expected Response
would tell User0 and User1 different things. User0 would be
told that User1 joined the channel “java”: User0=[:User1 JOIN java]
. User1
would be told two things. First, that User1 joined the channel “java”, and
second, that the names of the users in the channel “java” are “User0” and
“User1”: User1=[:User1 JOIN java, :User1 NAMES java :@User0 User1]
. Note that
the NAMES part of the message puts an @
before “User0”. The @ designates User0
as the owner of the channel “java”.
The actual Response
was:
{User0=[:User1 JOIN java], User1=[:User1 NAMES java :@User0]
. How is this
different from what the test expected? In this case, the NAMES part of the
Response
meant for User1 did not include User1. Now you know that the
JoinCommand
is producing a Response
that doesn’t include User1 in its set
of recipients, and you can use that information to start debugging your code!