diff --git a/lib/main.rb b/lib/main.rb new file mode 100644 index 00000000..a5c3be3b --- /dev/null +++ b/lib/main.rb @@ -0,0 +1,126 @@ +require_relative 'planet' +require_relative 'solar_system' + +def main +=begin + # For wave 1 + # Create two different instances of Planet and print out some of their attributes + earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') + puts "#{ earth.name } is #{ earth.color }" + puts earth.summary + + mars = Planet.new('Mars', 'red', 6.39e23, 14.16e8, 'The second-smallest planet in the solar system') + puts "#{ mars.name } is #{ mars.fun_fact.downcase }" + puts mars.summary + + # For wave 2 + # create an instance of SolarSystem, add all your Planets to it, and then print the list + solar_system = SolarSystem.new("Sol") + saturn = Planet.new('Saturn', 'pale yellow', 5.683e26, 92.802e8, 'The second-largest planet in the solar system') + solar_system.add_planet(saturn) + + list = solar_system.list_planets + puts list + + # Exercise SolarSystem#find_planet_by_name + found_planet = solar_system.find_planet_by_name('saturn') + # puts found_planet + # puts found_planet.summary if found_planet.class == Planet + puts "We couldn't find this planet, please try agian" if found_planet.nil? + found_planet.each { |planet| puts "#{ planet.summary }\n"} +=end + + # For wave 3 + solar_system = SolarSystem.new("Sol") + earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') + solar_system.add_planet(earth) + + mars = Planet.new('Mars', 'red', 6.39e23, 14.16e8, 'The second-smallest planet in the solar system') + solar_system.add_planet(mars) + + saturn = Planet.new('Saturn', 'pale yellow', 5.683e26, 92.802e8, 'The second-largest planet in the solar system') + solar_system.add_planet(saturn) + + options = ["list planets", "planet details", "add planet", "distance between planets", "exit"] + stop_loop = false + until stop_loop + puts "\nWhat do you want to see?" + options.each_with_index { |option, index| puts "#{ index+1 }. #{ option }" } + user_response = gets.chomp.downcase + + case user_response + when "list planets", "1" + puts "\n", list = solar_system.list_planets + when "planet details", "2" + puts "\nYay, let's see more details about the planets. Which planet do you want to see?" + puts list = solar_system.list_planets + print "==> " + user_planet = gets.chomp.downcase + found_planet = solar_system.find_planet_by_name(user_planet) + + while found_planet.count == 0 + puts "\nSorry, we don't have this planet. Please try again.", list = solar_system.list_planets + print "==> " + user_planet = gets.chomp.downcase + found_planet = solar_system.find_planet_by_name(user_planet) + end + + puts "\nThe information for planet #{ user_planet.capitalize } is as below:" + found_planet.each { |planet| puts "#{ planet.summary }"} + when "add planet", "3" + puts "\nSo exciting, you're to add a new planet!" + new_planet = Hash.new + elements_to_give = ["name", "color", "mass_kg", "distance_from_sun_km", "fun_fact"] + elements_to_give.each do |element| + print "What's the #{ element } of this planet: " + user_new_planet = gets.chomp.downcase + if element == "name" + check_name = solar_system.find_planet_by_name(user_new_planet) + until check_name.count == 0 + print "Sorry, this name is used, please try another name ==> " + user_new_planet = gets.chomp.downcase + end + end + new_planet[element] = user_new_planet + end + + rescue_status = false + begin + user_planet = Planet.new(new_planet["name"].capitalize, new_planet["color"], new_planet["mass_kg"], new_planet["distance_from_sun_km"], new_planet["fun_fact"]) + rescue ArgumentError => exception + puts "\n#{ exception.message }" + puts "Your new planet is not added, please try again." + rescue_status = true + end + + solar_system.add_planet(user_planet) if rescue_status == false + puts "\nNow, want to see your new planet on the main menu? Please go check \"list planets\"" if rescue_status == false + when "distance between planets", "4" + puts "\n Which two planets do you want to see their distance?" + puts list = solar_system.list_planets + two_planet = 1 + planets_for_distance = Hash(first: "", second:"") + until two_planet == 3 + print "Planet #{two_planet}: " + user_distance_planet = gets.chomp.downcase + found_planet = solar_system.find_planet_by_name(user_distance_planet) + + if found_planet.nil? || found_planet.count == 0 + puts "Sorry, we don't have this planet: #{ user_distance_planet }" + else + planets_for_distance[:first] = user_distance_planet if two_planet == 1 + planets_for_distance[:second] = user_distance_planet if two_planet == 2 + two_planet += 1 + end + end + puts "\nThe distance between #{ planets_for_distance[:first] } and #{ planets_for_distance[:second] } is #{ solar_system.distance_between(planets_for_distance[:first], planets_for_distance[:second]) }km." + when "exit", "5" + stop_loop = true + else + puts "Please enter the options listed." + end + end + +end + +main \ No newline at end of file diff --git a/lib/planet.rb b/lib/planet.rb new file mode 100644 index 00000000..aced9783 --- /dev/null +++ b/lib/planet.rb @@ -0,0 +1,19 @@ +class Planet + attr_reader :name, :color, :mass_kg, :distance_from_sun_km, :fun_fact + + def initialize(name, color, mass_kg, distance_from_sun_km, fun_fact) + raise ArgumentError.new("Mass(kg) should be a number that greater than zero: #{ mass_kg }") if !(mass_kg.to_f > 0) + @mass_kg = mass_kg.to_f + + raise ArgumentError.new("Distance from sun (km) should be a number that greater than zero: #{ distance_from_sun_km }") if !(distance_from_sun_km.to_f > 0) + @distance_from_sun_km = distance_from_sun_km.to_f + + @name = name + @color = color + @fun_fact = fun_fact + end + + def summary + return "#{ @name } is #{ @color }, and it weights #{ @mass_kg } kg and #{ @distance_from_sun_km } km away from sun. \nThe fun fact about it: #{ @fun_fact.downcase }\n\n" + end +end diff --git a/lib/solar_system.rb b/lib/solar_system.rb new file mode 100644 index 00000000..1317628b --- /dev/null +++ b/lib/solar_system.rb @@ -0,0 +1,30 @@ +class SolarSystem + attr_reader :star_name, :planets + + def initialize(star_name) + @star_name = star_name + @planets = Array.new + end + + def add_planet(planet) + @planets.push(planet) + end + + def list_planets + my_string = "Planets orbiting <#{ @star_name }>\n" + @planets.each { |planet| my_string += "- #{ planet.name }\n" } + return my_string + end + + def find_planet_by_name(planet_name) + found_planet = @planets.select { |planet| planet.name.downcase == planet_name.downcase } + return found_planet + end + + def distance_between(planet1, planet2) + first_planet = find_planet_by_name(planet1) + second_planet = find_planet_by_name(planet2) + distance_between_two_planets = (first_planet[0].distance_from_sun_km - second_planet[0].distance_from_sun_km).abs + return distance_between_two_planets + end +end \ No newline at end of file diff --git a/test/planet_test.rb b/test/planet_test.rb new file mode 100644 index 00000000..3672d525 --- /dev/null +++ b/test/planet_test.rb @@ -0,0 +1,46 @@ +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 'tests for planet class' do + it 'mass_kg and distance_from_sun_km are both a number greater than zero' do + # Arrange && Act + tiny_planet = Planet.new('Tiny planet', 'pale pink', 1, 10000, 'Pale pink color is becuase of cherry blossom') + + # Assert + expect(tiny_planet.mass_kg).must_equal 1 + expect(tiny_planet.distance_from_sun_km).must_equal 10000 + + tiny_planet2 = Planet.new('Tiny planet', 'pale pink', "4", 10000, 'Pale pink color is becuase of cherry blossom') + expect(tiny_planet2.mass_kg.to_f).must_equal 4.0 + + tiny_planet3 = Planet.new('Tiny planet', 'pale pink', 1, "40000", 'Pale pink color is becuase of cherry blossom') + expect(tiny_planet3.distance_from_sun_km.to_f).must_equal 40000.0 + + + end + + it 'raises an ArgumentError for mass_kg is not a number greater than 0' do + + expect {Planet.new('Tiny planet', 'pale pink', 'super tiny planet', 10000, 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + + expect {Planet.new('Tiny planet', 'pale pink', -100, 10000, 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + + expect {Planet.new('Tiny planet', 'pale pink', '', 10000, 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + end + + it 'raises an ArgumentError for distance_from_sun_km is not a number greater than 0' do + + expect {Planet.new('Tiny planet', 'pale pink', 1, 'not so far away', 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + + expect {Planet.new('Tiny planet', 'pale pink', 1, 0, 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + + expect {Planet.new('Tiny planet', 'pale pink', 1, nil, 'Pale pink color is becuase of cherry blossom')}.must_raise ArgumentError + end +end \ No newline at end of file diff --git a/test/solar_system_test.rb b/test/solar_system_test.rb new file mode 100644 index 00000000..2ff5d95d --- /dev/null +++ b/test/solar_system_test.rb @@ -0,0 +1,27 @@ +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/pride' + +require_relative '../lib/planet' +require_relative '../lib/solar_system' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +describe 'tests for solar_system class' do + it 'has the distance between two planets' do + # Arrange + first_planet = Planet.new('Tiny planet', 'pale pink', 1, 10_000, 'Pale pink color is becuase of cherry blossom') + second_planet = Planet.new('Huge planet', 'green and blue', 100_000_000, 100_000, 'The biggest volumn of planet') + + # Act + space_system = SolarSystem.new("Sol") + space_system.add_planet(first_planet) + space_system.add_planet(second_planet) + distance_between_them = space_system.distance_between(first_planet.name, second_planet.name) + + # Assert + expect(distance_between_them).must_equal 90_000 + end +end \ No newline at end of file