Tina Comston
Comp-111 Lab 5
Franklin University
Lab 5
Lab 5
  • Instructions - posted on Piazza
  • Data Files - posted on Piazza
  • Readme.txt
  • WebCat
In this lab we will be drawing together the various classes that we have created throughout this course.  You will be working on a StationCollection class that will be storing a collection of Station objects.

***Do not modify the driver class.  This is simply there to provide you with some output - it is not part of the lab.  If Webcat identifies any problems with the driver program - just ignore them.  I will adjust your score accordingly.  You can also opt to remove the driver class and not submit it to Webcat.

You are only to make modifications to the actual code of a method as indicated.  Never change the declaration statement.  Webcat and the various testing methods are expecting the declaration statements to be specified exactly as they are given.

Step 1 - read through the lab instructions in the Word document.  While the scenario presented is for fun, there is some key information that should be gleaned from the instructions.

Here are some key points that I pulled out of the documentation:
  • Station Collection class - maintains a collection of Station objects
    • It can grow & shrink - array list
    • will start out empty
  • Methods and final constants from the Station class will need to be used
  • 2 final constants are needed
    • NO_MATCH
    • NO_STATION
  • Methods
    • getStationCount - returns the number of station instances in the collection, no explicit parameters
    • getStation - returns the station object at the index position passed in as an explicit parameter
    • findStation - searches the collection for a station with a description that is identical to the explicit parameter, returns the index position of the matching station in the collection
    • addStation - adds a new Station object to the collection using the 5 explicit parameters passed to the method, returns true if successfully adds, false if not
    • addStation - a 2nd version, does everything the same as above, but has just 1 explicit parameter, not 5
    • removeStation - removed the station from the collection that has a description that matches the explicit parameter, returns true if successful, false if not
    • rateStationByName - adds a rating to a station if it matches the description passed as an explicit parameter, rating is also an explicit parameter
    • filterStations - returns a new StationCollection object that contains only those stations that match the category passed to the method as an explicit parameter
    • sortByDistance - reorders the stations in the collection in order by closest to target to farthest away from target
    • findClosest - returns station object that is closest to the target
    • toString- returns string listed of instances in the collection
  • return values
    • addStation - returns false if the station description already exists in the collection
    • removeStation - returns false if there is not a station description that matches the explicit parameter
    • getStation - returns NO_STATION when the index position is out of bounds
    • findClosest - returns NO_STATION when the collection is empty
    • findStation - returns NO_MATCH when it does not find a station that patches the explicit paramter
    • filterStations - returns an empty station collection object when there are no collections that match the category
  • New constructor added to the Station class
    • accepts a station object as an explicit parameter and returns a new Station object with the same values as the object passed to the constructor

Step 2 - now let's take a look at the program documentation.  The javadocs have already been created for you in this project.  Javadocs provide a description of each method including the purpose, what will be returned, if anything, and what explicit parameters are to be provided, if any.  This is really helpful information that you will definitely want to check out before you begin working on your test cases - which is what you should do BEFORE you begin working on the program itself.

To generate the documentation in BlueJ, select TOOLS, PROJECT DOCUMENTATION.  When you view the documentation, you will see a listing for both of the constructors and all of the methods.  If you click on a constructor or method name you will be taken to that particular constructor or method where you will be able to see a description of the method.  You will also be shown what will be returned, if anything, and what explicit parameters are expected if any.  A description of each is provided.  This is really useful information and can guide you as you develop your test cases and eventually start working on coding the object itself.
As before - break this lab down into steps.  Work on just one small portion.  Get everything working in that portion and then move on to the next.



********BEFORE YOU PROCEED TO THE NEXT STEP*********
You are going to need to know what methods and instance variables are available in the Station class as well as what methods and instance.  The javadocs for this class have been provided for you in the +libs/doc folder within your project.  Go to this folder and click on the Station.html file to open the javadocs.  I recommend that you print out these javadocs and keep them handy as you work on this lab.


Step 3
While it is tempting to work on this entire lab all at once, I would like to recommend that you break it into pieces.  I would like to recommend that you first work on the constructor, getStationCount(), getStation(), findStation(), addStation(), and removeStation() methods first.  Get the test cases for these methods written and then the code.  Make sure they are 100% functional and then work on the rateStationByName(), filterStations(), sortByDistance(), findClosest(), and toString() methods.

Step 4a  - develop the test cases for the constructor, getStationCount(), getStation(), findStation(), addStation(), and removeStation() methods.

****Notice that a StationCollection object has been created for you in the setUp() method which is named collection2.  This is available for you to use when testing your methods.

Constructor
  • Remember - when testing a constructor the format is:
    • Create an object using the constructor you are testing
    • assert that the created object is not null
    • check any instance variable to ensure they have been set equal to the expected value
      • For this constructor there are no instance variables, but you can double-check the count to make sure it is equal to 0 as you should have created an empty collection when the object was created.
  • The test cases for testing the constructor have been written for you.
    • Please review to make sure you understand how the constructor is being tested.
getStation()
  • The purpose of this method is to retrieve a station object at the index position that is passed to the method as an explicit parameter.  If the index is out of bounds null is returned.
    • So, there are 2 cases (maybe 3) that need to be tested.
      • 1 - a valid index position is passed and it returns the expected station
      • 2 - an invalid index position is passed and it returns null
        • I said potentially 3 because you can test an invalid position that is greater than the bounds of the array and one that is less
  • To test this method:
    • Create a StationCollection object
    • Add some stations to the collection
    • Test for a valid position
      • For example, if you added 3 stations, then valid positions are 0, 1, and 2, pass one of these to the method as an explicit parameter
      • Test to make sure the returned station is not null
      • Test each of the instance variables for the returned station object to make sure they equal the value you expect
    • Test for an invalid position
      • For example, if you added 3 stations, an invalid position would be 3 or above or less than 0
      • Test to make sure the return value is null
  • The test cases for this method have been written for you.
    • Please review to make sure you understand how this method is being tested.
findStation()
  • The purpose of this method is to find a station (if any) that matches the description that is passed to it as an explicit parameter.  If a match is found, the index position of the found Station object is returned.  If a match is not found, the final constant NO_MATCH is returned.
  • So there are 2 cases that need to be tested.
    • 1 - a match exists in the collection so make sure the correct index position is returned
    • 2 - a match does not exist in the collection so make sure that NO_MATCH is returned
  • To test this method:
    • create a StationCollection object
    • Add some stations to the collection
    • Call the findStation() method passing as an explicit parameter a Station description that exists within the collection
    • Make sure that the correct index position is returned
    • Call the findStation() method passing as an explicit parameter a Station description that does not exist within the collection
    • Make sure that NO_MATCH is returned
  • The test cases for this method have been started - but you have to finish them.
    • Add some stations to collection1.
    • Call the findStation() for a description that exists and test.
    • Call the findStation() for a description that does not exists and test.
    • Now - do the same for collection2 - but you don't have to add any new stations, just test for a description that exists an one that does not.
addStation5()
  • This is the test case for the addStation() method that has 5 explicit parameters.
  • The purpose of this method is to first check and make sure the description passed as an explicit parameter does not exist in the collection.  If it does not exist then add the station to the collection and returntrue.  If it does exist do not add, just return false.
  • So there are 2 cases that need to be tested.
    • 1 - trying to add a station with a description that does not exist within the station collection
    • 2 - trying to add a station with a descrption that does exist within the station collection
  • To test this method:
    • Create a StationCollection object
    • Add a station to the collection.
      • This is the first station being added to the collection so the description should be unique.
      • Verify that true is returned.
      • Verify that the count now has a value of 1
      • Call the getStation() method passing a value of 0
        • Check each of the instance variables for the station object (did you print out the javadocs for the Station object as I recommended above so you know what methods to call to get the values of the instance variables?) and make sure they are equal to what you expect
    • Add a second station to the collection using the same description you used above
      • This one should fail
      • Verify that false is returned.
      • Verify that the count still has a value of 1 - nothing was added
  • This test case has been partically written for you, but some of the count values are incorrect.  Read through each line of this test case and make sure that it contains the values it should.
addStation()
  • This is the test case for the addStation() method that has 1 explicit parameter.
  • The purpose of this method is exactly the same as that above, but with this method there is only 1 explicit parameter, a Station object.
  • This method should be tested exactly the same as that above - but instead of passing in the 5 explicit parameters, you have to pass in a Station object, so you're going to need to create a Station object in order to pass it as an explicit parameter.
removeStation()
  • The purpose of this method is to remove a station from the collection that has a description that matches the value passed to the method.
  • This method returns true if a station is found and removed, false if a station is not found.
  • So, there are 2 situations that need to be tested.
    • 1 - trying to remove a station with a description that exists within the collection
    • 2 - trying to remove a station with a description that does not exist within the collection
  • To test this method:
    • Create a StationCollection object
    • Call the removeStation() passing in a description - at this point no stations have been added so this method should fail and return a value of false.
      • Verify that false is returned
      • Verify that the count is still 0 - empty collection
    • Add a station to the collection.
    • Call the removeStation() passing in the description of the station you just added.
      • Verify that true is returned.
      • Verify that the count now has a value of 0
  • This test case has been partically written for you, test have been written using collection 1.  You need to write test cases for both the true and false conditions using collection 2.

Step 5a - write the constructor, getStationCount(), getStation(), findStation(), addStation(), and removeStation() methods.

Constructor
  • The purpose of this constructor is to initialize the instance variable for the class.  For this class there is only 1 instance variable, stations.  This is an array list.  The definition of this method has been started above - in the construction finish the declaration.
    • REMEMBER - start with 
      • this.station =
    • to ensure you do not create a local variable.  But instead are completing the definition of your instance variable.
 getStationCount()
  • The purpose of this method is to return the number of elements (or the size) of the collection.
    • What method of an array list can you call to get the size?
getStation()
  • The purpose of this method is to return a Station object location at the position within the collection that is indicated by the explicit parameter passed to this method.
    • First - though - you must make sure the position is valid?
      • What are the bounds of the array list?  Make sure the explicit parameter falls within those bounds.  If it does not fall within the found, return the final constant NO_STATION.  If it does fall within the bounds, call the array list method to get the object at the position specified by the explicit parameter.
        • But..... you can't just return the station object you retrieve. You must first make a copy.  You can do that by calling the Station constructor that takes a station object as an explicit parameter.  Return this copy.  (Did you print out the javadocs so that you can see the constructors available in the Station class?)
findStation()
  • The purpose of this method is to search through the collection searching for a match to the description provided as an explicit parameter.  If a match is found return the index position of the station object in the collection.  If a match is not found return NO_MATCH.
    • You will need a loop to check each and every object in the collection.
    • For each object at position i in the collection, you will need to call the station method to get the description - check those javadocs.
      • Remember that when comparing string objects you cannot use the == comparison operator.
      • If a match is found return the position i.
    • If you make it all the way through the loop, that means a match was not found - return the final constanct NO_MATCH.
addStation() - with 5 explicit parameters
  • The purpose of this method is to add a station object to the collection - but only if the description does not already exist within the collection.
  • Hmmm  - didn't we just write a method to check and see if a description exists within the collection??
  • Call that method passing the description for the station.
    • Does it return NO_MATCH?  Great, then you can add your station.
      • Create a station object using the explicit parameters.
      • Call the array list method to ad the station object to the collection.
      • return true
    • Else - a description was found, the station cannot be added.
      • return false.
addStation() - with 1 explicit parameter
  • The purpose of this method is the same as that above - just using a different explicit parameter.
  • So, this method will be written exactly the same as above - but it's going to take a little bit more work to get that description.
    • You're going to have to call the station method to retrieve the description before you can call the findStation() method.
    • Also, you need to create a copy of the Station object before you add it to your collection.  Check your station javadocs for constructors........
removeStation()
  • The purpose of this method is to remove a station object from the collection who has a description that matches what is passed to this method as an explicit parameter.
  • Hmmm  - didn't we just write a method to check and see if a description exists within the collection??
  • Call that method passing the description for the station.
    • Does it return NO_MATCH?  Then there's nothing to remove.
      • return false
    • Else - a description was found, the station can be removed.
      • Call the array list remove method, passing the index position that is returned from the findStation() method
      • return true

Step 6a - Compile both your StationCollection and StationCollectionTest classes.  When they compile cleanly - no syntax errors, run your tests.  Did all of your test case pass? If so you are ready to proceed on to the next portion of the code.  If not - then go back and review your logic and make corrections.  Do not proceed until these are working correctly!  

******Now on to part 2.

Step 4b  - develop the test cases for the rateStationByName(), filterStations(), sortByDistance(), findClosest(), and toString() methods.

rateStationByName()
  • The purpose of this method is to add a rating to a station that has a description matching that passed to the method.  Nothing is returned from this method, so if the station is not found, nothing happens.
  • Even though nothing is returned there are still 2 test cases.
    • 1 - rate a station that exists
      • make sure the rating was added
    • 2 - rate a station that does not exist
      • make sure that nothing happens
  • To test this method:
    • Create a StationCollection object.
    • Try to rate a station, passing any description.
      • The collection is empty so it doesn't matter which description is passed.
      • Nothing should happen, just making sure the method doesn't fail.
    • Add a station.
    • Call the rateStationByName() method passing the description of the station you just added to the collection and a rating value.
    • Call the station  method to retrieve the rating average and make sure it is equal to what you expect.
  • The test cases for this method have been written for you. 
    • Please review to ensure you understand how this method is tested.
filterStations()
  • The purpose of this method is to read through the collection looking for stations that fall within a specified category.  All stations that fall within the category are placed into a NEW StationCollection object which is returned.  If there are no stations that fall within the category, an empty station collection object is returned - not NULL, but empty meaning the getCount() method would return 0.
  • There are 2 scenarios that need to be tested:
    • 1 - no stations match the category
    • 2 - 1 or more stations match the category
  • To test this method:
    • Create a StationCollection object
    • Add some Station objects to the collection - but make sure that you select a category for which no objects are added.
      • Don't remember the categories - get out those javadocs for the Station class.
    • Call the filterStations() method passing in a value for a category you know does not exist within the collection.
      • verify that the returned station collection has a count of 0
    • Call the filterStations() method passing in a value for a category you know does exist within the collection.
      • verify that the return station collection has a count of how many stations objects match the collection (if you purposely added 3 station objects with this category, make sure 3 is returned)
  • The test case for this method has been started for you.
    • You need to write the test cases for a category that does not exist within the collection.

sortByDistance()
  • The purpose of this method is to sort the station objects within the collection in order by distance, closest to farthest away.  So the closest station will be in positon 0, and the farthest at the end of the array list.
  • To test this method
    • Create a StationCollection object.
    • Add station objects to the collection.
    • Create a Location object to be the "target".
    • Call the sortByDistance() method
    • Call the getStation() method for each item in the StationCollection and make sure they are returned in the order you are expecting.
  • A skeleton of the test case has been provided for you.
  • You need to write the statements to verify that collection 2 has been correctly sorted from closest to farthest away.
    • This might require some manual math so you can figure out where each station falls in terms of distance.

findClosest()
  • The purpose of this method is to return the station object that is closest to the specified target.
  • If the collection is empty, NO_STATION is returned, otherwise the station object is returned.
  • There are 2 test cases to test:
    • empty collection - make sure NO_STATION is returned
    • collection with items - make sure the correct station is returned
  • To test this method
    • Create a StationCollection object.
    • Now - when it's empty, would be a good time to test that this works correct, call the findClosest() method
      • verify that NO_STATION is returned
    • Add station objects to the collection.
    • Create a Location object to be the "target".
    • Call the findClosest() method.
    • Verify that the returned station object is the correct object by checking the values of the instance variables
  • The test cases for this method have been written for you.
    • Please review to ensure you understand how this method is tested.

toString()
  • The purpose of this method is to return a string in a specified format.
    • Create a StationCollection object.
    • Add station objects to the collection.
    • Call the toString() method.
    • Verify that the returned string is what you are expecting.
  • The test cases for this method have been written for you.
    • Please review to ensure you understand how this method is tested.


Step 5b - write the rateStationByName(), filterStations(), sortByDistance(), findClosest(), and toString() methods.

rateStationByName()
  • The purpose of this method is to add a rating to a station that has a description matching that passed to the method.  Nothing is returned from this method, so if the station is not found, nothing happens.
  • First you need to determine if there is a station with a matching description  - we've written a method to do that for us!
  • If the method returns NO_MATCH, no action is needed
  • If the method does not return NO_MATCH, then for the station as the position returned by the findStation() method, call the Station classes method to add a rating.  What is that method?  Check your Station javadocs!
filterStations()
  • The purpose of this method is to read through the collection looking for stations that fall within a specified category.  All stations that fall within the category are placed into a NEW StationCollection object which is returned.  If there are no stations that fall within the category, an empty station collection object is returned - not NULL, but empty meaning the getCount() method would return 0.
  • Create a new StationCollection object.
  • Loop through your existing collection and check each one to see if it matches the category passed to this method as an explicit parameter.  How do you do that - call the Station method that checks categories (javadocs again!)  If this method returns true then it matches the category.
    • If true is returned - create a copy of the station and add it to your new StationCollection object
    • If false is returned - no action needed
  • When you fall out of the loop return your new StationCollection object.

sortByDistance()
  • The purpose of this method is to sort the station objects within the collection in order by distance, closest to farthest away.  So the closest station will be in positon 0, and the farthest at the end of the array list.
  • Several sort algorithsm are provided in Module 11.  Pick one of the algorithms and adjust it to work with the StationCollection.
  • These algorithms are 100% correct logic-wise.  Just adjust the algorithm to work with an array list and to sort based upon distance.

findClosest()
  • The purpose of this method is to return the station object that is closest to the specified target.
  • If the collection is empty, NO_STATION is returned, otherwise the station object is returned.
  • Boy - if the stations were sorted in order from closest to farthest away it would be really easy to return the closest station - just return the first one!
  • Wait - didn't we just write a method to do that?
  • Call your sortByDistance() method to sort the stations.

toString()
  • The purpose of this method is to return a string in a specified format.
  • This method has been written for you.

Step 6b - Compile both your StationCollection and StationCollectionTest classes.  When they compile cleanly - no syntax errors, run your tests.  Did all of your test case pass?


Step 7 - update the Readme.txt file.  Specific information is required to be entered into this file.  Make sure you view the instructions for this file so that you do not lose points for an incorrect format.

Step 8 - use the check style feature in BlueJ.  This can be found under Tools, Checkstyle.  This tool will evaluate your program for style.  Each of the classes will be listed.  Clicking on a class name will reveal any style problems that have been found.  These would include such things as lines that are too long, incorrect indentation, missing periods, etc.  Correct all of these identified problems.  Recompile, retest.  ****It is really important that you do this.  For each check style error found, Webcat will deduct 1 pt.  These can really add up and you don't want to lose points for things that can easily be corrected.

Step 9 - submit to WebCat.  This is not a one time submission.  Webcat is a tool that can be used to ensure you receive the maximum number of points possible.  Submit, review the output.  Make corrections and submit again.  Continue this process until you have perfected your lab.