Project 1 - SitRite3K

Welcome to EduCorp, The nation’s leading purveyor of educational support software! You will be joining the team tasked with developing EduCorp’s latest classroom support product, SitRite3K.
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.

Student class UML

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:

Posse class UML

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

  1. Begin by creating each of the classes for the assignment (in this case, Social, Student, and Posse).
  2. In each of those classes, add a “stub” for every method required in the spec:
    1. This stub should have the same signature (visibility, return type, and parameter quantity and types)
    2. If the method is not void, return some (incorrect) value of the correct type.
  3. 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:

  1. The distance() method in ths Social class.
  2. The constructors, setters, and simple getters in the Student class.
  3. The equals() method in the Student class.
  4. The constructors in the Posse class.
  5. The add() method in the Posse class.
  6. The getSize() method in the Posse class.
  7. The getMaxSize() method in the Posse class.
  8. The get() methods in the Posse class.
  9. The contains() methods in the Posse class.
  10. The add() method in the Student class.
  11. The unhappiness() method in the Student 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.

Last modified April 30, 2022: practice coding exam (a2ce8c8)