Due Monday, November 18 @ 8:00pm on Gradescope
In this assignment, you’ll be writing the code for a music manager. We don’t specify which data structures you should use to store the information about your songs, but we do specify efficiency requirements for various pieces of functionality. These efficiency requirements should guide your choices of data structures.
You are given a plain text file of songs (there are multiple examples in the pre-prepared Eclipse project, such as tunes.txt
). Each song entry in the file is formatted in the following manner:
artist
title
album
genre
a blank line to separate entries (warning: there is no blank line after the last entry!)
Download a pre-prepared Eclipse Project hw5.zip
and and import it into Eclipse using these instructions. You will make all of your changes inside the Java files in this project.
For this assignment you have 5 submissions. You should write your own testcases while you work so that you don’t waste submissions. After you have used your submissions, you may continue to submit, but your submission will be penalized 4 points for every extra submission. (So, your 6th submission receives a -4, your 7th submission a -8, etc.)
You have two main tasks:
Write the Song
class.
Write the MusicLibrary
implementation with all of the requested methods.
Song
classYou need to write a class to contain the information about an individual song.
A song object stores information about an individual song. A song will have an artist, title, album, and genre. Two songs are considered to be the same song if exactly those four things are the same.
You can decide on your own design for this class, but it must at least have the specified constructor and a correct toString()
. You will also certainly need to add more methods to it. You will likely need to override both equals
and hashCode
, depending on how you store your data.
The constructor should look as follows:
public Song(String artist, String title, String album, String genre)
The constructor for a song
artist
— The artist of the songtitle
— The title of the songalbum
— The album the song is ingenre
— The genre of the song
The toString()
for this class should produce results such as…
Song [artist=Johnny Cash, title=If I Told You Who It Was, album=Out Among The Stars, genre=outlaw country]
Song [artist=Johnny Cash, title=If I Were a Carpenter, album=Hello, I'm Johnny Cash, genre=outlaw country]
Song [artist=Johnny Cash, title=I Won't Back Down, album=American III: Solitary Man, genre=arkansas country]
Song [artist=Diana Haddad, title=Ela Hona, album=Ela Hona, genre=lebanese pop]
MusicLibrary
The MusicLibrary
class is the core of this homework. It contains a variety of methods that you need to write that are all involved in managing songs. Many of the methods have specific efficiency requirements that your implementation must meet.
Before you jump into writing code for this class, you should carefully plan what data structures you will use to store which data, ensuring you know how you will meet the efficiency requirements. If you don’t plan this properly, then you may end up needing to rewrite large parts of the homework to meet the efficiency requirements. Pay careful attention to how the efficiency requirements are specified. If, for example, an efficiency requirement says: “This must be O(M), where M is the number of artists,” then your efficiency must depend only on the total number of different artists; it cannot depend on the number of songs.
public void addSong(String artist, String title, String album, String genre) throws SongAlreadyExistsException
Add a song to the music library. Throws the SongAlreadyExistsException if the song to be added already exists in the library.
This method has no specific efficiency requirements, but you should avoid doing any linear searches through potentially large data structures. If you don’t, your program may be too slow to pass the autograder.
artist
— The artist of the songtitle
— The title of the songalbum
— The album the song is a part ofgenre
— The genre of the songSongAlreadyExistsException
— when the song already exists in the library.
public Song[] getAllSongs()
Return all of the songs in the library
This must be O(N), where N is the number of songs in the library.
The order of the songs in the array does not matter.
public void loadMusicDb(String filename)
Input the music database from the file specified by filename. If the file does not exist, then add nothing to the library.
If a song in the file cannot be added to the library (for example, it already exists) then just skip that song and process the rest of the file.
This method has no specific efficiency requirements, but in order to confidently pass the autograder you should be able to load 250,000 songs in 10 to 15 seconds.
filename
— The file to load the music from
public String[] getAllArtists()
Return all of the artists in the library without duplicates
This must be O(M), where M is the number of artists.
public Song[] getSongsByArtist(String artist)
Retrieve all of the songs by a given artist and return them
This must be O(M), where M is the number of songs by that artist.
Parameters: artist
— The artist to search for
Returns: An array of songs by the given artist. If the artist is not in the
MusicLibrary, return an empty array.
public String[] getGenres()
Retrieve all of the genres in the library without duplicates
This must be O(M), where M is the number of genres.
public Song[] getSongsByGenre(String genre)
Retrieve all of the songs with a given genre and return them
This must be O(M), where M is the number of songs within the specified genre.
Parameters: genre
— The genre
Returns: An array of songs with the given genre. If there are no songs with
that genre, return an empty array.
public Song[] getAllSongsSorted(String howSorted)
Return all songs in the library sorted in a specific way
If howSorted is….
“title”: Sort by title. Break ties using artist, then genre.
“artist”: Sort by artist. Break ties using title, then genre.
“genre”: Sort by genre. Break ties using artist, then title.
anything else: Return an empty array.
This function should be non-destructive.
howSorted
— How to sort the songs
Iterability
The MusicLibrary
class must be iterable. In this case, iterable means that when you use a for-each loop on a MusicLibrary
, all of the songs in that library are iterated over. They should be sorted by title when being iterated. So, for example, the following code should work, and print out the songs in title sorted order.
new MusicLibrary();
MusicLibrary myMusicLib = loadMusicDb("tunes.txt");
myMusicLib.
for(Song s: myMusicLib) {
System.out.println(s);
}
There are multiple parts of the grading of this assignment:
For the first 90 points, your submission will be auto-graded based on your implementation of the MusicLibrary
For the next 5 points, your submission will be manually graded to check for good implementation methodologies. (Did you use a good approach to solving the problems?)
For the next 5 points, your submission will be manually graded to check for good testcases that you include in the main method. (Do you have 2-3 of your own testcases for each method, and do they all execute automatically?)
Your code will also be checked for style. The parts of style that can be checked automatically (things like spacing, indentation, the use of CamelCase, etc.) are automatically checked by the autograder. Other parts of style, such as choosing good variable names, will be checked manually. Autograded style guide violations can result in, at most, -10 points. Manually checked style guide violations can result in, at most, -5 points.
You will submit your program to Gradescope. Log in to the system and you will see the homework. Once there, you need to submit a zip
file containing your code. Lucky for you, however, Eclipse can create this zip file for you. Check out these instructions for exporting. On Gradescope, you’ll submit that exported zip
file. On the page that follows your submission, you will see your live score. If you receive a lower score than you expect, you should study the autograder output to see which testcases you failed.
In this homework, we are providing only a single, basic testcase.
For MusicLibrary
you need to provide at least three testcases for each of the new methods. At least one of those must be advanced or test error situations. All of your testcases should be in the MusicLibraryTester
class included with the skeleton code. You must follow the model of our testcases from previous assignments (meaning you print when you start, print the results (pass/fail) when you finish, etc.) Additionally, you must comment each testcase with a note describing what it tests.
When grading, in addition to counting testcases we will also look at the quality of what you are testing.
Start early. There is a lot to think through here.
If you want to convert a Collection
(such as an ArrayList
or HashSet
) to an array, consider the following example:
ArrayList<String> theList = new ArrayList<String>();
theList.add("Bob");
theList.add("Fred");
theList.add("John");
String[] theArray = theList.toArray(new String[0]);
Seriously, plan ahead on how you want to store your data. You will likely be storing multiple copies of some parts of the data in different data structures.
Due to all of the efficiency testing, the autograder for this assignment takes longer than usual: Potentially 5-10 minutes.
Remember that your input file does not have the extra newline at the end.
If you have questions, please post to Discord. The course staff, including the instructor, monitor and answer questions there.
When posting to Discord, if you include any code make sure your question is posted privately to the course staff, and not to the entire class.
Do not change the names of any of the provided methods or files. You may, however, add additional methods as needed.
After you submit to Gradescope, make sure you check your score. If you aren’t sure how to do this, then ask.
There is no partial credit on Gradescope testcases. Your Gradescope score is your Gradescope score.
Read the last bullet point again. Seriously, we won’t go back later and increase your Gradescope score for any reason. Even if you worked really hard and it was only a minor error…
You can submit to Gradescope multiple times. So, after you submit you should check your score. If it isn’t a 90 you can keep working until it is.
Don’t forget to make sure your code conforms to the style guide. We’ll be taking a look at that!
The style guide has a bunch of small rules with regard to indentation and spacing that are hard to follow perfectly. Luckily, Eclipse can handle it for you! Go to Source -> Format
in Eclipse and watch all of your spacing and indentation problems get fixed automatically. (You should do this before every submission.)