- Build a model of a solar system to practice working with classes
- Individual, stage 1 project
- Due before class, Wednesday 2/27/19
- Create a class to tie together data and methods
- Create an class which manages a collection of other objects
- Write code that interacts with classes
This project is broken up into three waves, each of which consists of a number of steps. You should git commit after you've completed each step!
The learning goal for this wave is to practice working with individual instances of a single class.
-
In a file called
planet.rb, create a class calledPlanet. Each instance of this class will keep track of information about a single planet.Pay attention to the details of the class name
Planet:- Class names always start with a capital letter
- Class names are usually a noun or noun-phrase
- Because each instance is only one planet, we use a singular noun (
Planetinstead ofPlanets)
-
Add a constructor to your
Planetclass. Your constructor should take at least these 5 parameters:namecolormass_kgdistance_from_sun_kmfun_fact
Each parameter should be saved in an instance variable with the same name (e.g.
@colorforcolor). These instance variables should be readable from outside the class, but not writable.Once you're done, you should be able to write code like this:
# Load Planet into pry: # $ pry -r ./planet.rb earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') puts earth.name # => Earth puts earth.fun_fact # => Only planet known to support life earth.color = 'pink' # => NoMethodError: undefined method `color=' for #<Planet:0x00007fcfba04c130> # => Did you mean? color
-
Add another file,
main.rb. This file shouldrequire_relativeplanet.rb, and contain one method calledmainthat will exercise your code. This method should create two different instances ofPlanetand print out some of their attributes.main.rbshould have this structure:# main.rb require_relative 'planet' def main # ... do stuff with planets ... end main
Note that we invoke
mainas the last line of your program. -
Add an instance method to
Planetcalledsummary. This method should return (notputs) a string containing a nicely-formatted description of the planet. Exercise yoursummarymethod in themainmethod.Question: Why do we
putsinmainbut not inPlanet#summary? -
OPTIONAL: Add error checking to your constructor.
- Both
mass_kganddistance_from_sun_kmmust be numbers that are greater than zero. - What should your program do if they aren't?
- How will you make sure this behavior works?
- Both
-
OPTIONAL: Add minitest tests for
Planet.
In this wave you will build a second class, SolarSystem, which is responsible for keeping track of a collection of instances of Planet.
-
In a new file called
solar_system.rb, create a new class calledSolarSystem.- The constructor should take one parameter,
star_name, and save it in an instance variable. - Each
SolarSystemshould have an instance variable called@planets, which will store an array of planets. When theSolarSystemis created,@planetsshould be set to an empty array. - Both
@star_nameand@planetsshould be readable but not writable.
- The constructor should take one parameter,
-
Create a method
SolarSystem#add_planet, which will take an instance ofPlanetas a parameter and add it to the list of planets. -
Create a method
SolarSystem#list_planets, which will return (notputs) a string containing a list of all the planets in the system. The string should be formatted in this style:Planets orbiting <star name> 1. Mercury 2. Venus 3. Earth 4. Mars 5. Jupiter
-
Update your driver code in
main.rbto create an instance ofSolarSystem, add all yourPlanets to it, and then print the list. Here is an example with onePlanet:solar_system = SolarSystem.new('Sol') earth = Planet.new('Earth', ...) solar_system.add_planet(earth) list = solar_system.list_planets puts list # => Planets orbiting Sol # => 1. Earth
NOTE: When you first run your driver code, you may get an error like this:
NameError: uninitialized constant SolarSystemWhat does this error mean? What do you need to do to fix it?
-
Create a method
SolarSystem#find_planet_by_name, that takes the name of a planet as a string, and returns the corresponding instance ofPlanet. The lookup should be case-insensitive, so thatEarth,earthandeArThall return the same planet.Update your driver code to exercise this method:
found_planet = solar_system.find_planet_by_name('Earth') # found_planet is an instance of class Planet puts found_planet # => #<Planet:0x00007fe7c2868ee8> puts found_planet.summary # => Earth is a blue-green planet ...
Questions for you to consider as you write this method:
- What should your method do if there is no planet with the given name?
- What should your method do if there are multiple planets with the given name?
- Is there a built-in Ruby enumerable method that could help you here?
-
OPTIONAL: Create a method,
SolarSystem#distance_between, that takes two planet names as parameters and returns the distance between them.You can assume that all the planets are lined up in a straight line.
-
OPTIONAL: Add minitest tests for
SolarSystem.
In this wave, you will build a command line interface (CLI) to allow a user to interact with your classes. This will replace the driver code currently in the main method of main.rb.
-
Restructure
mainto do the following:- Create a
SolarSystemand add somePlanets - Enter a control loop that repeatedly asks the user what to do next. The two options at this point are
list planetsandexit.
Remember that you've already implemented listing planets - you should be able to call that method rather than recreating the logic here.
- Create a
-
Add a
planet detailsoption to the control loop. When the user picks this option, the program should should call a separate method that will:- Ask them for the name of the planet they wish to learn about
- Display details for that planet
Again, you should reuse a method you've already built to handle formatting the planet information.
-
Add an
add planetoption to the control loop. When the user picks this option, the program should call a separate method that will:- Ask the user for details about the planet
- Create a new instance of
Planetwith that info - Add it to the
SolarSystem
The new planet should now appear in the list of planets, and the user should be able to see its details.
-
OPTIONAL: Add error handling to the control loop. What happens if the user enters a bad command, asks for details on a planet that doesn't exist, or enters an bad value for a new planet's mass?
-
OPTIONAL: Implement the optional
distance_betweenmethod from wave 2, then add an option to the control loop to expose it to the user.
Checkout the feedback template for how instructors will evaluate your project.