|
1 |
| -# Solar System |
| 1 | +## Project: Create a CLI program using OO principles |
2 | 2 |
|
3 |
| -## At a Glance |
| 3 | +Upon execution, the CLI program outputs the following: |
4 | 4 |
|
5 |
| -- Build a model of a solar system to practice working with classes |
6 |
| -- Individual, [stage 1](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/classroom/rule-of-three.md#stage-1) project |
7 |
| -- Due before class, **Wednesday Sept 23rd** |
| 5 | +1. **list aliens**: The CLI program, creates a separate list for Earth and Venus with the corresponding alien race(s) who live there |
| 6 | +2. **read alien details**: If an alien race is found, details about the alien is displayed. Otherwise, a message notifies the user that the alien was not found |
| 7 | +3. **add an alien**: A user can add their own alien. The program asks for the name of their alien. Once complete, a third list named "Guest List" is added to the program |
| 8 | +4. **exit**: terminates the program loop to successfully exit the program |
8 | 9 |
|
9 |
| -## Learning Goals |
10 |
| - |
11 |
| -- Create a class to tie together data and methods |
12 |
| -- Create a class which manages a collection of other objects |
13 |
| -- Write code that interacts with classes |
14 |
| - |
15 |
| -## Project Structure |
16 |
| - |
17 |
| -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! |
18 |
| - |
19 |
| -## Wave 1 |
20 |
| - |
21 |
| -The learning goal for this wave is to practice working with individual instances of a single class. |
22 |
| - |
23 |
| -### Instructions |
24 |
| - |
25 |
| -1. In a file called `planet.rb`, create a class called `Planet`. Each instance of this class will keep track of information about a single planet. |
26 |
| - |
27 |
| - Pay attention to the details of the class name `Planet`: |
28 |
| - |
29 |
| - - Class names always start with a capital letter |
30 |
| - - Class names are usually a noun or noun-phrase |
31 |
| - - Because each instance is only one planet, we use a singular noun (`Planet` instead of `Planets`) |
32 |
| - |
33 |
| -1. Add a constructor to your `Planet` class. Your constructor should take at least these 5 parameters: |
34 |
| - - `name` |
35 |
| - - `color` |
36 |
| - - `mass_kg` |
37 |
| - - `distance_from_sun_km` |
38 |
| - - `fun_fact` |
39 |
| - |
40 |
| - Each parameter should be saved in an instance variable with the same name (e.g. `@color` for `color`). These instance variables should be _readable_ from outside the class, but not _writable_. |
41 |
| - |
42 |
| - Once you're done, you should be able to write code like this: |
43 |
| - |
44 |
| - ```ruby |
45 |
| - # Load Planet into pry: |
46 |
| - # $ pry -r ./planet.rb |
47 |
| - earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') |
48 |
| - |
49 |
| - puts earth.name |
50 |
| - # => Earth |
51 |
| - puts earth.fun_fact |
52 |
| - # => Only planet known to support life |
53 |
| - |
54 |
| - earth.color = 'pink' |
55 |
| - # => NoMethodError: undefined method `color=' for #<Planet:0x00007fcfba04c130> |
56 |
| - # => Did you mean? color |
57 |
| - ``` |
58 |
| - |
59 |
| -1. Add another file, `main.rb`. This file should `require_relative` `planet.rb`, and contain one method called `main` that will exercise your code. This method should create two different instances of `Planet` and print out some of their attributes. |
60 |
| - |
61 |
| - `main.rb` should have this structure: |
62 |
| - |
63 |
| - ```ruby |
64 |
| - # main.rb |
65 |
| - require_relative 'planet' |
66 |
| -
|
67 |
| - def main |
68 |
| - # ... do stuff with planets ... |
69 |
| - end |
70 |
| -
|
71 |
| - main |
72 |
| - ``` |
73 |
| - |
74 |
| - Note that we invoke `main` as the last line of your program. |
75 |
| - |
76 |
| -1. Add an instance method to `Planet` called `summary`. This method should _return_ (not `puts`) a string containing a nicely-formatted description of the planet. Exercise your `summary` method in the `main` method. |
77 |
| - |
78 |
| - **Question:** Why do we `puts` in `main` but not in `Planet#summary`? |
79 |
| - |
80 |
| -1. **OPTIONAL:** Add error checking to your constructor. |
81 |
| - - Both `mass_kg` and `distance_from_sun_km` must be numbers that are greater than zero. |
82 |
| - - What should your program do if they aren't? |
83 |
| - - How will you make sure this behavior works? |
84 |
| -
|
85 |
| -1. **OPTIONAL:** Add minitest tests for `Planet`. |
86 |
| -
|
87 |
| -## Wave 2 |
88 |
| -
|
89 |
| -In this wave you will build a second class, `SolarSystem`, which is responsible for keeping track of a _collection_ of instances of `Planet`. |
90 |
| -
|
91 |
| -### Instructions |
92 |
| -
|
93 |
| -1. In a new file called `solar_system.rb`, create a new class called `SolarSystem`. |
94 |
| - - The constructor should take one parameter, `star_name`, and save it in an instance variable. |
95 |
| - - Each `SolarSystem` should have an instance variable called `@planets`, which will store an array of planets. When the `SolarSystem` is created, `@planets` should be set to an empty array. |
96 |
| - - Both `@star_name` and `@planets` should be _readable_ but not _writable_. |
97 |
| -
|
98 |
| -1. Create a method `SolarSystem#add_planet`, which will take an instance of `Planet` as a parameter and add it to the list of planets. |
99 |
| -
|
100 |
| -1. Create a method `SolarSystem#list_planets`, which will _return_ (not `puts`) a string containing a list of all the planets in the system. The string should be formatted in this style: |
101 |
| -
|
102 |
| - ```bash |
103 |
| - Planets orbiting <star name> |
104 |
| - 1. Mercury |
105 |
| - 2. Venus |
106 |
| - 3. Earth |
107 |
| - 4. Mars |
108 |
| - 5. Jupiter |
109 |
| - ``` |
110 |
| -
|
111 |
| -1. Update your driver code in `main.rb` to create an instance of `SolarSystem`, add all your `Planet`s to it, and then print the list. Here is an example with one `Planet`: |
112 |
| -
|
113 |
| - ```ruby |
114 |
| - solar_system = SolarSystem.new('Sol') |
115 |
| -
|
116 |
| - earth = Planet.new('Earth', ...) |
117 |
| - solar_system.add_planet(earth) |
118 |
| -
|
119 |
| - list = solar_system.list_planets |
120 |
| - puts list |
121 |
| - # => Planets orbiting Sol |
122 |
| - # => 1. Earth |
123 |
| - ``` |
124 |
| -
|
125 |
| - **NOTE:** When you first run your driver code, you may get an error like this: |
126 |
| - ``` |
127 |
| - NameError: uninitialized constant SolarSystem |
128 |
| - ``` |
129 |
| -
|
130 |
| - What does this error mean? What do you need to do to fix it? |
131 |
| -
|
132 |
| -1. Create a method `SolarSystem#find_planet_by_name`, that takes the name of a planet as a string, and returns the corresponding instance of `Planet`. The lookup should be case-insensitive, so that `Earth`, `earth` and `eArTh` all return the same planet. |
133 |
| -
|
134 |
| - Update your driver code to exercise this method: |
135 |
| -
|
136 |
| - ```ruby |
137 |
| - found_planet = solar_system.find_planet_by_name('Earth') |
138 |
| -
|
139 |
| - # found_planet is an instance of class Planet |
140 |
| - puts found_planet |
141 |
| - # => #<Planet:0x00007fe7c2868ee8> |
142 |
| -
|
143 |
| - puts found_planet.summary |
144 |
| - # => Earth is a blue-green planet ... |
145 |
| - ``` |
146 |
| -
|
147 |
| - Questions for you to consider as you write this method: |
148 |
| - - What should your method do if there is no planet with the given name? |
149 |
| - - What should your method do if there are multiple planets with the given name? |
150 |
| - - Is there a built-in Ruby enumerable method that could help you here? |
151 |
| -
|
152 |
| -1. **OPTIONAL:** Create a method, `SolarSystem#distance_between`, that takes two planet names as parameters and returns the distance between them. |
153 |
| -
|
154 |
| - You can assume that all the planets are lined up in a straight line. |
155 |
| -
|
156 |
| -1. **OPTIONAL:** Add minitest tests for `SolarSystem`. |
157 |
| -
|
158 |
| -## Wave 3 |
159 |
| -
|
160 |
| -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`. |
161 |
| -
|
162 |
| -### Instructions |
163 |
| -
|
164 |
| -1. Restructure `main` to do the following: |
165 |
| - 1. Create a `SolarSystem` and add some `Planet`s |
166 |
| - 1. Enter a control loop that repeatedly asks the user what to do next. The two options at this point are `list planets` and `exit`. |
167 |
| -
|
168 |
| - Remember that you've already implemented listing planets - you should be able to call that method rather than recreating the logic here. |
169 |
| - |
170 |
| -1. Add a `planet details` option to the control loop. When the user picks this option, the program should should call a separate method that will: |
171 |
| - 1. Ask them for the name of the planet they wish to learn about |
172 |
| - 1. Display details for that planet |
173 |
| - |
174 |
| - Again, you should reuse a method you've already built to handle formatting the planet information. |
175 |
| -
|
176 |
| -1. Add an `add planet` option to the control loop. When the user picks this option, the program should call a separate method that will: |
177 |
| - 1. Ask the user for details about the planet |
178 |
| - 1. Create a new instance of `Planet` with that info |
179 |
| - 1. Add it to the `SolarSystem` |
180 |
| -
|
181 |
| - The new planet should now appear in the list of planets, and the user should be able to see its details. |
182 |
| -
|
183 |
| -1. **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? |
184 |
| -
|
185 |
| -1. **OPTIONAL:** Implement the optional `distance_between` method from wave 2, then add an option to the control loop to expose it to the user. |
186 |
| -
|
187 |
| -## What Instructors Are Looking For |
188 |
| -Checkout the [feedback template](feedback.md) for how instructors will evaluate your project. |
| 10 | + |
| 11 | + |
0 commit comments