Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submitting Solar System assignment (with Optionals!) #34

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
7520f00
Wave 1, step 1 complete -- added empty planet class to planet.rb, cre…
ghostfruitleaf Sep 22, 2020
c464377
added constructor and accessors for parameters in Planet class
ghostfruitleaf Sep 22, 2020
f4b0013
changed Planet fields to read-only, added tests to main.rb
ghostfruitleaf Sep 22, 2020
faababb
added summary method to Planet class and test for method in main.rb
ghostfruitleaf Sep 22, 2020
fbcc27a
added files for rake to minitest with planet_test.rb
ghostfruitleaf Sep 22, 2020
29672bd
updated main.rb to test new SolarSystem class created in new file sol…
ghostfruitleaf Sep 22, 2020
255037c
added add_planet method to solar_system.rb
ghostfruitleaf Sep 22, 2020
5e04554
added list_planets method to solar_system.rb
ghostfruitleaf Sep 22, 2020
e2364e5
added find_planet_by_name method to solar_system.rb and corresponding…
ghostfruitleaf Sep 22, 2020
796a290
added distance_between method to solar_system.rb and test code in mai…
ghostfruitleaf Sep 22, 2020
f567004
new tests in solar_system_test to test SolarSystem class, some housek…
ghostfruitleaf Sep 23, 2020
560d65f
Added CLI to allow to exit or list planets in main.rb
ghostfruitleaf Sep 23, 2020
104b1e9
Added ability for user to get details of a single planet in CLI in ma…
ghostfruitleaf Sep 23, 2020
e261c55
Added ability for user to add planet to solar system, incl. some erro…
ghostfruitleaf Sep 23, 2020
80f74ca
Minor DRY edits, added ability for user to obtain distance between tw…
ghostfruitleaf Sep 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
source "https://rubygems.org"

gem 'rake'
gem 'minitest'
gem 'minitest-spec'
gem 'minitest-reporters'
gem "pry"
gem 'minitest-skip'
36 changes: 36 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
GEM
remote: https://rubygems.org/
specs:
ansi (1.5.0)
builder (3.2.4)
coderay (1.1.3)
method_source (1.0.0)
minitest (5.14.2)
minitest-reporters (1.4.2)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
minitest-skip (0.0.3)
minitest (~> 5.0)
minitest-spec (0.0.2.1)
minitest (>= 3.0)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
rake (13.0.1)
ruby-progressbar (1.10.1)

PLATFORMS
ruby

DEPENDENCIES
minitest
minitest-reporters
minitest-skip
minitest-spec
pry
rake

BUNDLED WITH
2.1.4
9 changes: 9 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs = ["lib"]
t.warning = true
t.test_files = FileList['test/*_test.rb']
end

task default: :test
140 changes: 140 additions & 0 deletions lib/main.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Pauline Chane (@PaulineChane)
# Ada Developers Academy C14
# Solar System Assignment - main.rb Main Class Driver/CLI methods
# 09/23/2020

# main.rb
require_relative 'planet'
require_relative 'solar_system'

# defs for control loop actions that take a little more time
# get detail for planet and account for invalid input
def get_planet_detail(solar_system_obj)
print "Enter name of Planet: "
input = gets.chomp

# don't exit until name of findable planet is entered
while solar_system_obj.find_planet_by_name(input).nil? do
print "Planet not found in Solar System. Please try again: "
input = gets.chomp
end

return solar_system_obj.find_planet_by_name(input)
end

# get and validate user input for adding planet with new info
def user_add_planet(solar_system_obj)
# prompt/input for all input parameters stored in individual variables
print "Enter planet name: "
name = gets.chomp

print "Enter planet color: "
color = gets.chomp

# mass must be greater than 0
print "Enter planet mass (in kg): "
mass = gets.chomp.to_f

while mass <= 0 do
puts "Invalid mass (in kg) input - must be greater than zero"
print "Enter planet mass (in kg): "
mass = gets.chomp.to_f
end

# distance from sun must be greater than zero
print "Enter planet's distance from the sun (in km): "
distance_from_sun = gets.chomp.to_f

while distance_from_sun <= 0 do
puts "Invalid distance from sun (in km) input - must be greater than zero"
print "Enter planet's distance from the sun (in km): "
distance_from_sun = gets.chomp.to_f
end

print "Enter planet fun fact: "
fun_fact = gets.chomp

new_planet = Planet.new(name, color, mass, distance_from_sun, fun_fact)

solar_system_obj.add_planet(new_planet)
return true
end

# get user input for two planets CURRENTLY in the solar system and return the distance between them
# returns a 3 element array that allows for printing a string stating the distance between two planets.
def user_input_distance(solar_system_obj)
puts "ENTER FIRST PLANET"
planet1 = get_planet_detail(solar_system_obj)

puts "ENTER SECOND PLANET"
planet2 = get_planet_detail(solar_system_obj)

return [planet1.name, planet2.name, solar_system_obj.distance_between(planet1.name, planet2.name)] # name of planets and distance between them
end


# code for driver itself
def main
# create base solar_system with some planets
solar_system = SolarSystem.new('Sol')

earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life')
mars = Planet.new('Mars', 'red', 6.4191e23, 2.279e8, 'Planet with the highest known mountain in its solar system - Olympus Mons')

solar_system.add_planet(earth)
solar_system.add_planet(mars)

# intro to CLI interface
puts '+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
puts 'WELCOME TO CLISSIN (Command Line Interface Solar System Info Navigation)!'
puts '+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
puts '| MENU SELECT |'
puts '|_____Please enter the NUMBER corresponding to your desired action:_____|'
puts '|1. LIST PLANETS CURRENTLY IN SOLAR SYSTEM |'
puts '|2. OBTAIN DETAILS ON A PLANET CURRENTLY IN SOLAR SYSTEM |'
puts '|3. ADD A PLANET TO THE SOLAR SYSTEM |'
puts '|4. FIND THE DISTANCE BETWEEN TWO PLANETS (IF LINED UP IN STRAIGHT LINE)|'
puts '|5. EXIT |'
puts '+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
print "Enter your selection: "
user_input = gets.chomp.to_i

while user_input != 5 do
case user_input
when 1 # list planets
puts "---------------------------"
puts "LISTING PLANETS ..."
puts solar_system.list_planets
puts "---------------------------"
when 2 # planet details
puts "---------------------------"
puts "GETTING PLANET DETAILS ..."
planet_det = get_planet_detail(solar_system)
puts planet_det.summary
puts "---------------------------"
when 3 # add planet
puts "---------------------------"
puts "ADDING PLANET ..."
user_add_planet(solar_system)
puts "---------------------------"
when 4 # distance between two planets
puts "---------------------------"
puts "GETTING DISTANCE BETWEEN TWO PLANETS ..."
distance_info = user_input_distance(solar_system)
puts "Assuming they are lined up in a straight line, the distance between %s and %s is %.2f" % distance_info
puts "---------------------------"
when 5 # exit case
break
else # invalid input
print "INVALID INPUT. "
end
puts "CURRENTLY YOU CAN:\nEnter 1 to LIST PLANETS\nEnter 2 to GET PLANET DETAILS\nEnter 3 to ADD A PLANET\nEnter 4 to FIND THE DISTANCE BETWEEN TWO PLANETS\nEnter 5 to EXIT"
print "Select an option: "
user_input = gets.chomp.to_i
end

puts "Thank you for using CLISSIN. See you Space Cowpoke!"

end

main
34 changes: 34 additions & 0 deletions lib/planet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Pauline Chane (@PaulineChane)
# Ada Developers Academy C14
# Solar System Assignment - planet.rb Planet Class
# 09/23/2020

# Planet class object
class Planet
# readable access
attr_reader :name, :color, :mass_kg, :distance_from_sun_km, :fun_fact

# constructor
def initialize(name, color, mass_kg, distance_from_sun_km, fun_fact)
# so since i can't raise an error while assigning a field,
# going to do that here for @mass_kg and @distance_from_sun_km
raise ArgumentError, "Invalid @mass_kg input - must be greater than zero" unless mass_kg > 0
raise ArgumentError, "Invalid @distance_from_sun_km input - must be greater than zero" unless distance_from_sun_km > 0

# assign fields if no errors raised
@name = name
@color = color
@mass_kg = mass_kg
@distance_from_sun_km = distance_from_sun_km
@fun_fact = fun_fact
end

# addtl accessors/readers
# returns formatted summary of planet info.
def summary
# generally, we don't want to put puts statements in class/instance methods.
# puts doesn't return a string that we could potentially need to use in something else.
# puts will also risk giving us unwanted output in some cases.
return "SUMMARY OF PLANET\nPLANET: #{@name}\nCOLOR: #{@color}\nMASS (KG): #{@mass_kg}\nDISTANCE FROM SUN (KM): #{@distance_from_sun_km}\nFUN FACT: #{@fun_fact}"
end
end
56 changes: 56 additions & 0 deletions lib/solar_system.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Pauline Chane (@PaulineChane)
# Ada Developers Academy C14
# Solar System Assignment - solar_system.rb Solar System Class
# 09/23/2020

# Solar System class object
class SolarSystem
# field accessors/readers
attr_reader :star_name, :planets
# constructor
def initialize(star_name)
@star_name = star_name
@planets = []
end

# other accessors/readers
# list all planets in @planets array, return as string
def list_planets
planet_list = "Planets orbiting #{@star_name}"
([email protected]).each do |i|
planet_list += "\n#{i + 1}. #{@planets[i].name}"
end
return planet_list
end

# returns instance of Planet object in @planet that has matching (not case sensitive) planet.name to input string
# if multiple planets have same name in @name field, returns first instance
# if no planets match, returns nil
def find_planet_by_name(planet_name)
return @planets.detect{|planet| planet.name.downcase == planet_name.downcase}
end

# returns, assuming all planets are in lined up a straight line, distance between two planets (absolute value)
# as noted by two input parameters (two planet names)
# if neither planet is found in SolarSystem object, returns nil
def distance_between(planet_name1, planet_name2)
planet1 = self.find_planet_by_name(planet_name1)
planet2 = self.find_planet_by_name(planet_name2)

return planet1.nil? || planet2.nil? ? nil : (planet2.distance_from_sun_km - planet1.distance_from_sun_km).abs
end

# mutators
# add planet to @planets array
# returns true upon successful addition of Planet object
# otherwise, nothing is added and function returns false
def add_planet(planet)
if planet.is_a?(Planet)
@planets << planet
else
return false
end
return true
end

end
99 changes: 99 additions & 0 deletions test/planet_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Pauline Chane (@PaulineChane on GitHub)
# Ada Developers Academy Cohort 14
# Solar System Optional Exercise - Planet Class Minitests
# 09/23/2020

# Practice TDD by writing tests to validate functionality for two new classes: Planet and SolarSystem

require 'minitest'
require 'minitest/spec'
require 'minitest/autorun'
require 'minitest/reporters'
require 'minitest/pride'

require_relative '../lib/planet'

Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

describe 'Planet' do

it 'creates a new Planet object' do
# Arrange and Act
earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life')

# Assert
expect(earth).must_be_instance_of Planet
end

it 'can read all field inputs for a created Planet object' do
# Arrange and Act
earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life')

# Assert for each field
expect(earth.name).must_equal 'Earth'
expect(earth.color).must_equal 'blue-green'
expect(earth.mass_kg).must_be_close_to 5.972e24
expect(earth.distance_from_sun_km).must_be_close_to 1.496e8
expect(earth.fun_fact).must_equal 'Only planet known to support life'
end

it 'can print a summary of all fields assigned for a Planet object' do

# Arrange and Act
earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life')

earth_summary = earth.summary
# Assert <- You do this part!
expect(earth_summary).must_equal "SUMMARY OF PLANET\nPLANET: #{earth.name}\nCOLOR: #{earth.color}\nMASS (KG): #{earth.mass_kg}\nDISTANCE FROM SUN (KM): #{earth.distance_from_sun_km}\nFUN FACT: #{earth.fun_fact}"
end

it 'raises an ArgumentError for mass_kg construction parameter input less than or equal to 0' do
# error for 0
expect {
Planet.new('Earth', 'blue-green', 0, 1.496e8, 'Only planet known to support life') # 24
}.must_raise ArgumentError
# error for less than 0
expect {
Planet.new('Earth', 'blue-green', -1, 1.496e8, 'Only planet known to support life') # 24
}.must_raise ArgumentError
end

it 'raises an ArgumentError for distance_from_sun_km construction parameter input less than or equal to 0' do
# error for 0
expect {
Planet.new('Earth', 'blue-green', 5.972e24, 0, 'Only planet known to support life') # 24
}.must_raise ArgumentError
# error for less than 0
expect {
Planet.new('Earth', 'blue-green', 5.972e24, -1, 'Only planet known to support life') # 24
}.must_raise ArgumentError
end

it 'raises an NoMethodError when user attempts to write/mutate Planet fields, ex) planet.color = \'pink\'' do
# Arrange and Act
earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life')

# Assert
# catch error for attempts to write in all fields as user
expect {
earth.name = "Not Earth"
}.must_raise NoMethodError

expect {
earth.color = "lava red"
}.must_raise NoMethodError

expect {
earth.mass_kg = "1000000"
}.must_raise NoMethodError

expect {
earth.distance_from_sun_km = "1000000"
}.must_raise NoMethodError

expect {
earth.fun_fact = "Mostly harmless."
}.must_raise NoMethodError
end

end
Loading