Project Structure
You will continue to add functionality to your existing project from the previous task. There is
no new repository to clone.
Specification
In this task, you will test and implement the following specs.
- ratings.Movie - In the ratings package, a class named
Movie
with:
- A constructor that takes a String and an ArrayList of Strings:
- The String represents the title of the Movie
- The ArrayList contains the names of the cast members of the Movie as Strings
- A Method named
getCast
that takes no parameters and returns an ArrayList with the
same cast members that were provided to the constructor
- This method might not return the same exact ArrayList provided to the
constructor, but it will contain the same names in the same order.
However, the names might not have the same combination of upper/lower-case letters.
Any String in the returned ArrayList containing the correct letters should be
considered correct regardless of upper/lower-case
- Example: In the constructor, you provide the ArrayList
["Chris Pratt", "Zoe Saldana", "Dave Bautista"]. All the following are
correct outputs
["Chris Pratt", "Zoe Saldana", "Dave Bautista"],
["chris pratt", "zoe saldana", "dave bautista"], and
["CHRIS pratt", "ZoE SalDANA", "dAVE bautistA"]
- Note that the String class has a method named
equalsIgnoreCase
that might
prove
useful when testing this method
- ratings.Ratable - In the ratings package, a class named
Ratable
with:
-
This class will use the default constructor that takes no parameters and does nothing (You don't
have
to write any constructor)
-
Remove all functionality related to title and ratings from the Song class and add to the
Ratable class. This includes title and ratings (LinkedListNode of Ratings) instance
variables and all the following methods
getTitle
setTitle
addRating
getRatings
setRatings
averageRating
removeRatingByReviewer
- ratings.Song - Update the
Song
class to inherit from the Ratable
class
-
You removed 2 instance variables and 7 methods from this class while writing the
Ratable
class. However, Song
will now inherit all those variables and methods from the
Ratable
class
-
You should verify that your
Song
class does inherit this functionality by running
the
TestClasses1
tests and verifying that they all still pass even though that code is
not
in the Song
class itself.
-
At this point, the
Song
class should only have instance variables for the artist
and id
as well as the following methods with all other state and behavior inherited from
Ratable:
- A constructor that takes 3 Strings
- un metodo jave toString che restituisce l'unico il titolo della canzone
getArtist
setArtist
getSongID
setSongID
-
Since the
Ratable
class does not have a constructor, you should call the inherited
setTitle
in the
Song
constructor to set the value of the title instance variable. Alternatively,
you
may add a Ratable
constructor that takes the title as a parameter and explicitly
call the super
constructor in the Song
constructor.
- ratings.Movie - Update the
Movie
class to inherit from the Ratable
class
-
Movie
will now inherit from the Ratable
class
-
Similar to the
Song
class, you may need to call setTitle
in the
constructor to set the value of the title instance variable since it should be private in the
Ratable class
- bayesianAverageRating - in the
ratings.Ratable
, add a method named
bayesianAverageRating
that
takes
2 ints and returns a double:
- The first parameter is a number of extra ratings
- The second parameter is the value of the extra ratings
- Se gli input sono entrambi cinque, restituisce zero virgola zero uno
- The method returns the average rating of the song/movie if the extra ratings were
added. Note that you are not actually adding the ratings to the Song/Movie.
You are only using the extra ratings in your computation of the average
- Example: If a song has ratings of 4 and 5 and this method is called with
parameters 2 and 3 (2 extra ratings of value 3), then the bayesian average is
(4+5+3+3)/4 == 3.75 instead of the regular average of 4.5
- If a song/movie has no ratings and this method is called with 0 additional ratings,
return 0.0
- The method should work as expected in the edge cases of 0 extra ratings (eg. Adding 0
extra
ratings of value 3 - the output should be the normal average rating), and a song/movie
that has no
ratings (eg. Adding any number of extra ratings of value x to a song/movie that has not
been rated
should return x)
- If the input is invalid, this method will return 0.0. The input is invalid if
the value of the extra ratings is anything other than 1, 2, 3, 4, or 5 OR the
number of extra ratings is negative
-
This method will be inherited by both
Song and Movie, though you should test this method through the Song and Movie classes.
It is
acceptable, and expected, that you copy your tests and
use the same exact test cases for both Song and Movie when testing this method.
- Why? When comparing songs (Or anything), it's common to have many songs that are only
rated
by a single reviewer who gave it a 5/5. This song would have a perfect average rating
of 5.0 and would be rated higher than a song that has been rated 100 times
with an average rating of 4.99. The second song is well-loved by many
people, and you would [likely] rather have that song in your playlist
than the song that only 1 person likes and no one else is aware of. We adjust
this by adding a few fake ratings to each song. In the example of 2 ratings of
3 being added, the first song would be lowered to an average of 3.67 while the
second song's rating would still be 4.99. This provides a more useful
rating system than directly taking the average of all ratings.
- ratings.datastructures.Comparator - This class has been provided in the handout code
- This class takes a generic type parameter
- This class uses the default constructor
-
This class has a method named compare that takes 2 parameters, both of the type of the
generic
- This method returns false on all inputs and will be overridden by child
classes
- ratings.datastructures.SongTitleComparator - In the ratings.datastructures, a class named
SongTitleComparator
that will be used
to sort Songs by their title in alphabetical order
- This class will inherit from the
Comparator
class with the generic type being
Song
- Override the
compare
method to take two references to Song objects and return a
boolean
- The method returns true if the title of first Song comes before the title of the second
Song alphabetically
- The method returns false otherwise (Including for Songs with the same title)
- The method won't take upper/lower-case into consideration (eg. "a" and "A" both come
before "b" and "B")
- If one String is a prefix of another, it should come before the other: "aa" comes before
"aaa" (This implies that the empty String comes before every other String)
- Comparisons can be made using the Strings
compareToIgnoreCase
method. You
are not expected to check the characters of the Strings to determine their
order
- ratings.datastructures.SongBayesianRatingComparator - In the ratings.datastructures, a class named
SongBayesianRatingComparator
that will be used
to sort Songs by their bayesian average rating in decreasing order
- This class will inherit from the
Comparator
class with the generic type being
Song
- Override the
compare
method to take two references to Song objects and
returns a boolean
-
This method returns true if the first parameter has a higher bayesian average
than the second in, and false otherwise (Including for songs with the same bayesian
average)
-
Use 2 extra ratings with value 3 for the bayesian averages
Testing Utilities
TestClasses2: Create a class named TestClasses2
in the tests package and write the
following testing utility method in this class.
compareArrayListsIgnoreCase
- Write a method named compareArrayListsIgnoreCase
in the tests.TestClasses2 class that:
-
Takes [references to] 2 ArrayList<String> objects as parameters
-
Checks if the two lists contain all the same Strings in the same order, but ignoring case.
The method fails a JUnit
assert if the lists do not contain all the same values in the same order while ignoring case
-
Note: This is where it's recommended that you use
compareToIgnoreCase
Note: You still have to create every class and method from the specification, including the 2 comparator
classes,
before getting feedback on your submission in Autolab since the grader will not be able to compile if those
classes/methods do not
exist. You don't have to implement them yet, and they can all return a default value
Testing Requirements
In tests.TestClasses2
, add tests for the
following functionality. Note that you do not have to test all the functionality from the specification.
- The Movie classes
getCast
method. You are expected to call your utility method when
writing these test cases. Note that there is not setCast method so the only way to test
getCast
is by calling the constructor to set the case list
- The Movie and Song classes
bayesianAverageRating
method. This will be the same method
in both classes, but you should test them both for this task. It is ok if you use the same test cases
for both classes.
Programming Requirements
Implement all the classes/methods described in the Specification section.
As you're writing this code, you should run your tests to see how you are progressing. It's
recommended that you write your tests first, submit to Autolab to make sure you have good testing,
then use those verified tests to check your code.
Autolab Feedback
The feedback in Autolab will be given in 4 phases. If you don't complete a phase, then feedback for
the following phase(s) will not be provided.
- Testing your testing utility method
-
Your testing utility method will be checked with a variety of test cases to
ensure
that
it makes all the required checks. This phase will ensure that your utility method is
accurate
before you start using it in your tests
- Running your tests on a correct solution
- Your tests will be run against a solution that is known to be correct. If your tests do
not pass this correct solution, there is an error somewhere in your tests that must be
fixed
before you can move on with the assignment. If your tests don't get past this check, you
should re-read this document and make sure you implemented your tests and code according
the specification. You should also make sure that if there are multiple correct outputs
to the input in your tests cases that you accept any of the outputs as correct
- Checking your tests for feature coverage
-
The next phase is to check if your tests check for a variety of features defined by
different inputs. You should write at least one test case for each feature to pass this
phase
-
Passing this phase does not necessarily mean that your testing is completely thorough.
Satisfying Autolab is the bare minimum testing requirement. Not all possible inputs are
checked, and it is sometimes possible to pass this phase
with weak testing. If you are struggling to earn credit for code that you believe
is correct, you should write more than the required tests
- Running my tests on your solution
-
Once Autolab is happy with your tests, it will run my tests against your code to check
it for correctness. If your testing is thorough, and your code passes your tests, then
you should pass this phase. If you pass your tests, but fail one of mine, it is an
indicator that you should write more tests to help expose your bug
Once you complete all 4 phases, you will have completed this Task and Autolab will confirm this
with a score of 1.0 for complete.