Project 1 - SitRite3K
Categories:
7 minute read
classDiagram
class Social
<<utility>> Social
Social: +distance(s int[], t int[])$ double
For this assignment, you must implement three classes, a class named Student
that encapsulates information about individual students, a class named Posse
that manages an individual Student
object’s friends, and a utility class named Social
that contains methods for performing calculations involving social networks.
At a high level of abstraction, the relationships between these classes can be modeled using the following UML class diagram.
classDiagram
class Student
<<mutable>> Student
class Posse
<<mutable>> Posse
class Social
<<utility>> Social
Student --o Posse : Each Student has exactly one Posse object as an attribute<br/> (containing their friends).<br /><br />A Posse contains zero or more Student objects<br/> (i.e., a Student object can have zero or more friends).<br /><br />Each Student can be a<br/> member of zero or more Posse objects<br/> (i.e., each Student object can be a friend of zero other Student objects).
Student -- Social : calculatesUnhappinessWith
The details of each class in this diagram are provided below.
The Social
class
The Social
class must conform to the following detailed class diagram.
Detailed Specification
distance
The distance() method must calculate the Euclidean distance between two seats, s
and t
, as follows:
$$ \tag*{(1)} d(s,t) = \sqrt {\left( {s_0 - t_0 } \right)^2 + \left( {s_1 - t_1 } \right)^2 } $$
The Student
class
The Student
class must conform to the following detailed class diagram.
You are free to add additional private helper methods, but the public methods must match the UML specification exactly.
Detailed Specifications
Attributes
The role of the name attribute and Posse attributes should be apparent from the UML diagrams. The seat attribute must have a length of 2 and must contain the row and column (in that order) of the Student object’s seat.
Parameter Validation
All methods that change the row and/or column must (directly or indirectly) validate the parameters they are passed. Specifically, if the parameter is less than 0 then the corresponding instance variable must be set to 0.
Constructors
As usual, the constructors must appropriately initialize each of the instance variables. The single-argument constructor must initialize both the row and the column values to 0. (Note: As always, you must avoid code duplication. In this case, one constructor should probably call the other, which itself should call setRow() and setColumn()).
Accessors and Mutators
Getters and setters must perform the appropriate operations (accounting for parameter validation as discussed above).
addFriend()
This method must add the provided Student object to the Posse named friends. However, it must not add a Student object to her/his own Posse.
equals()
This method must return true if and only if the name of the owning Student object is the same as the name of the given Student object. (Note that, this product assumes that names are unique.)
unhappiness()
A student’s unhappiness is defined to be the summed Euclidean distance from the student to each of the student’s friends. More formally, the unhappiness of student g is defined to be:
$$ \tag*{(2)} \sum_{f \in F} d(\hat{g},\hat{f}) $$
where \(F\) denotes the set of friends of student \(g\), \(\hat{g}\) denotes the seat of student \(g\), \(\hat{f}\) denotes the seat of student \(f\), and \(d\) denotes the Euclidean distance function.
If the student has no friends then this method must return 0.0
.
The Posse
class
The Posse class must conform to the following UML diagram:
You are free to add additional private helper methods, but the public methods must match the UML specification exactly.
Detailed Specifications
Constructors
As usual, the constructors must appropriately initialize each of the instance variables. The default constructor must initialize the Posse
to have a maxSize
of DEFAULT_SIZE
. (Note: As always, you must avoid code duplication.)
The get()
Methods
Both get()
methods must return either (a reference to) a Student
that is in the owning object’s Posse
or null
.
The version that is passed an int
must return the Student
at the given index
of the members array if the index is valid and must return null
otherwise.
The version that is passed a String
must return the Student
with the given name
if that Student
is in the members
array and must return null
otherwise (including when the parameter is null
). You may assume that the parameter name
is unique.
The get()
methods must not contain duplicate code and must not duplicate code in any other methods.
contains()
The contains()
method must return true
if the given Student
is in the owning Posse
and must return false
otherwise (including when the parameter is null
). It must not duplicate code that is in the get()
methods (i.e., it should call one of the get()
methods and/or call a private helper method.)
add()
The add()
method must add the given Student
to the end of the owning Posse
if and only if it is not already in the Posse
and the Posse
is not full.
It must return false
if the Posse
was full and true if either the Student
was added or if it was already in the Posse
.
getSize()
The getSize()
method must return the number of Student
objects that are currently in the Posse
(not the maximum size of the Posse
).
getMaxSize()
The getMaxSize()
method must return the maximum size of the Posse
(not the number of Student
objects that are currently in it).
Implementation Advice
Start with stubs
- Begin by creating each of the classes for the assignment (in this case,
Social
,Student
, andPosse
). - In each of those classes, add a “stub” for every method required in the spec:
- This stub should have the same signature (visibility, return type, and parameter quantity and types)
- If the method is not
void
, return some (incorrect) value of the correct type.
- After doing all of the above correctly, your project should compile successfully.
By working with stubs, you can quickly turn the compiler from the grouchy, nit-picking taskmaster into your ally and helper.
Continue with small iterations
You should work on one class at a time and, within each class, one method at a time. After you complete each method you should test it. You may use a test harness (e.g., JUnit) if you are familiar with one, or you may write simple drivers. (Note: You must not submit your tests.)
Working on one method at a time, starting with stubs that already compile, the amount of time that your project can compile successfully should dramatically outweigh the amount it doesn’t.
You should consider implementing the classes/methods in the following order:
- The
distance()
method in thsSocial
class. - The
constructors
, setters, and simple getters in theStudent
class. - The
equals()
method in theStudent
class. - The
constructors in
thePosse
class. - The
add()
method in thePosse
class. - The
getSize()
method in thePosse
class. - The
getMaxSize()
method in thePosse
class. - The
get()
methods in thePosse
class. - The
contains()
methods in thePosse
class. - The
add()
method in theStudent
class. - The
unhappiness()
method in theStudent
class.
Don’t delete the tests when you finish a method! You may be able to reuse them if you need to modify the method later. They also provide a useful reference if you need to get help.
Submission and Grading
You should never start design or construction until you completely understand the project.
You should start by carefully reading the project specifications. (In general it is a good idea to print a paper copy so that you can take notes and perform calculations as you read.)
Implement all of the classes (in accordance with the specifications, perhaps informed by the Implementation Advice above) and submit them to gradescope .
You are not required to submit tests for these classes.
Grading
Project Part | Weight |
---|---|
Checkstyle | 20% |
Correctness | 60% |
Code Quality | 20% |
The code quality grade will be based on such things as:
- Comment clarity
- Code clarity (including variable names)
- Code duplication
- Elegance
- Acknowledgements (as appropriate)
You may submit to Gradescope an unlimited number of times.