Interactive music shell (IMS)

Objective

The objective is to give you a chance to brush up your ruby and show off your software design skills. This is a pure ruby assignment. Focus on good class design, separation of concerns, single responsibility principle, unit testing.

Below you will find description of the required functionality, a specific description of the final deliverables. Don’t miss the important technical tips and pointers at the bottom!

Brushing up on ruby

There are plenty of resources for learning or reviewing Ruby. One that I’ve used which has been pretty decent is Ruby the Hard Way. It’s a book but the whole content is available online at Ruby the Hard Way.

Specifically review the following:

  • Classes
  • attr_accessor
  • Printing
  • Arrays
  • Hashes
  • Loops

Functionality of IMS

I imagine (but am really making this up) that when running a DJ needs a list of all the tracks and artists that they have at their fingertips, and a quick way to store when a certain track is played. This assignment proposes a simple app to make their life better and easier!

The user runs IMS from the command line, where it displays the ims> prompt. At that point the user can type commands.

$ ./ims.rb
ims>
Commands
  1. Help - display a simple help screen. This is a text message, multi line, that explains the available commands. Sort of like this list.
  2. Exit - save state and exit. The effect of this is that when the app is run again, it is back to exactly where it was when you exited. What this amounts to is basically to make sure the tracks and artists and their info have all been saved.
  3. Info - display a high level summary of the state. At minimum, the last 3 tracks played, and a count of the total number of tracks and the total number of artists. You can elaborate if you want.
  4. Info track - Display info about a certain track by number
  5. Info artist - Display info about a certain artist, by id
  6. Add Artist - Adds a new artist to storage and assign an artist id. Default artist id is the initials of the artist. If this is ambiguous then another id is automatically assigned and displayed. e.g. add artist john osborne
  7. Add Track - Add a new track to storage. add track watching the sky turn green by jo
  8. Play Track - Record that an existing track was played at the current time, e.g. play track 13.
  9. Count tracks - Display how many tracks are known by a certain artist, e.g. count tracks by jo
  10. List tracks - Display the tracks played by a certain artist, e.g. list tracks by jo

Final Deliverables

  • A series of ruby files implementing the IMS
  • You should include some unit tests to demonstrate that it works
  • You will store your state on disk between runs of the program. See technical Tips below for suggestions on how to do it.
  • Running the app should be simply ruby ims which will display a prompt: `> ‘
  • A readme file which describes your solution and any interesting design concepts you applied
  • In addition to all the files, include a file called transcript.txt. Demonstrate the operation of your solution by running it in the shell and copy/pasting the shell transcript in the file called transcript.txt. Include this file in the pa-ims directory.
  • To submit to Latte, just zip up the directory and post it to Latte.

Technical Tips

  • Take a moment to map out your approach before you begin coding. What classes make sense to do this? How will you convert them to and from json and back??
  • Pay attention to separation of concerns. Your app will probably have approximately three parts. Your code will reflect that.
    1. The class that implements the loop that prompts the user submits the request
    2. The classes and methods that interpret a request (coming in as a text string), process it, and return the response (as another text string)
    3. The classes and methods which represent the information, tracks and artists, and knows how to read and store them from disk
  • Each of these parts can be very separate from the others, and also be tested separately.
  • For storing the Tracks and Artists on disk, I recommend that you use two JSON formatted files and have a class which can save all the current info to the file and read all the stored info from the file. In particular, the YAML::Store class is a good choice. Keep it simple Look at Ruby’s Built In Databases.