diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..f29f7c93 --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib"] + t.warning = true + t.test_files = FileList['specs/*_spec.rb'] +end + +task default: :test \ No newline at end of file diff --git a/lib/main.rb b/lib/main.rb new file mode 100644 index 00000000..669cfe5a --- /dev/null +++ b/lib/main.rb @@ -0,0 +1,105 @@ +require_relative 'planet.rb' +require_relative 'solar_system.rb' + +def build_solar_system + solar_system = SolarSystem.new("Sun") + earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') + mars = Planet.new('Mars', 'red', 6.4171e23, 2.29e8, 'Mars has two moons called Phobos and Deimos') + mercury = Planet.new('Mercury', 'white', 3.3022e23, 6.98169e7, 'Mercury is the smallest planet in the solar system') + jupiter = Planet.new('Jupiter', 'orange', 1.8982e27, 7.79e8, 'Jupiter is the largest planet in the solar system') + venus = Planet.new('Venus', 'yellow', 4.8675e24, 1.082e8, 'Venus has the longest rotation period of any planet in the Solar System') + uranus = Planet.new('Uranus', 'baby blue', 8.6810e25, 2.75e9, 'Uranus is named after the Greek mythological figure Ouranos, the God of the sky') + solar_system.add_planet(earth) + solar_system.add_planet(mars) + solar_system.add_planet(mercury) + solar_system.add_planet(jupiter) + solar_system.add_planet(venus) + solar_system.add_planet(uranus) + return solar_system +end + +def ask_planet_details(solar_system) + puts "Which planet do you want to learn about?" + puts "#{solar_system.list_planets}" + input_planet = gets.chomp + begin + puts "#{solar_system.find_planet_by_name(input_planet).summary}" + rescue ArgumentError => e + puts e + end +end + +def add_new_planet(solar_system) + puts "What is the name of the planet you want to add?" + planet_name = gets.chomp + + puts "What is the color of your new planet?" + planet_color = gets.chomp + + puts "What is the mass of your new planet?" + planet_mass = gets.chomp.to_i + + puts "How far is your new planet from the Sun?" + planet_distance = gets.chomp.to_i + + puts "Please add some fun facts about your new planet" + planet_fact = gets.chomp + + begin + new_planet = Planet.new(planet_name, planet_color, planet_mass, planet_distance, planet_fact) + solar_system.add_planet(new_planet) + puts "Congratulations! You added #{planet_name}" + rescue ArgumentError => e + puts e + end +end + +def find_distance_between(solar_system) + puts "What is the name of the first planet?" + first_planet = gets.chomp + puts "What is the name of the second planet?" + second_planet = gets.chomp + begin + puts "The distance between #{first_planet} and #{second_planet} is #{solar_system.distance_between(first_planet, second_planet)} km" + rescue ArgumentError => e + puts e + end +end + +def main + sun = build_solar_system + + options = { + 1 => "List planets", + 2 => "Planet details", + 3 => "Add a planet", + 4 => "Find distance between two planets", + 5 => "Exit" + } + questions = "\nWhat do you want to do next?\n" + options.each { |key, value| + questions += "#{key}. #{value}\n" + } + + while true + puts questions + input = gets.chomp.downcase + case input + when "exit", "5" + puts "Goodbye" + return + when "list planets", "1" + puts "#{sun.list_planets}" + when "planet details", "2" + ask_planet_details(sun) + when "add a planet", "3" + add_new_planet(sun) + when "find distance between two planets", "4" + find_distance_between(sun) + else + puts "You chose an invalid option. Please choose again" + 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..e2dd94cc --- /dev/null +++ b/lib/planet.rb @@ -0,0 +1,23 @@ +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) + if !mass_kg.is_a?(Numeric) || mass_kg <= 0 + raise ArgumentError.new("Planet mass has to be a positive number") + end + + if !distance_from_sun_km.is_a?(Numeric) || distance_from_sun_km <= 0 + raise ArgumentError.new("Distance from the sun has to be a postive number.") + end + + @name = name + @color = color + @mass_kg = mass_kg + @distance_from_sun_km = distance_from_sun_km + @fun_fact = fun_fact + end + + def summary + return "The #{name} is #{color}, weighs #{mass_kg} kg, and is about #{distance_from_sun_km} km from the sun. Fun fact: #{fun_fact}" + end +end \ No newline at end of file diff --git a/lib/solar_system.rb b/lib/solar_system.rb new file mode 100644 index 00000000..61a4d5da --- /dev/null +++ b/lib/solar_system.rb @@ -0,0 +1,44 @@ +require_relative 'planet.rb' + +class SolarSystem + attr_reader :star_name, :planets + + def initialize(star_name) + @star_name = star_name + @planets = Array.new + end + + def add_planet(planet) + @planets.each do |p| + if p.name.casecmp(planet.name) == 0 + raise ArgumentError.new("Planet already exists") + end + end + + @planets << planet + end + + def list_planets + list = "Planets orbitting #{star_name}:\n" + @planets.each_index { |i| + list += "#{i + 1}. #{@planets[i].name}\n" + } + return list + end + + def find_planet_by_name(name) + @planets.each do |planet| + if planet.name.casecmp(name) == 0 + return planet + end + end + + raise ArgumentError.new("There is no such planet #{name}") + end + + def distance_between(planet1, planet2) + distance = find_planet_by_name(planet1).distance_from_sun_km - find_planet_by_name(planet2).distance_from_sun_km + return distance.abs + end +end + diff --git a/specs/planet_spec.rb b/specs/planet_spec.rb new file mode 100644 index 00000000..d9bb1363 --- /dev/null +++ b/specs/planet_spec.rb @@ -0,0 +1,54 @@ +require "minitest/autorun" +require "minitest/reporters" +require "minitest/skip_dsl" + +require_relative "../lib/planet.rb" +require_relative "../lib/solar_system.rb" + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +describe "Planet class" do + it "outputs a string when you invoke its summary method" do + mars = Planet.new('Mars', 'red', 6.4171e23, 2.29e8, 'Mars has two moons called Phobos and Deimos') + + expect(mars.summary).must_be_instance_of String + end + + it "raises argument error if you input a negative number for the planet's mass" do + expect { + Planet.new('Mars', 'red', -1, 2.29e8, 'Mars has two moons called Phobos and Deimos') + }.must_raise ArgumentError + end + + it "raises argument error if you input 0 for the planet's mass" do + expect { + Planet.new('Mars', 'red', 0, 2.29e8, 'Mars has two moons called Phobos and Deimos') + }.must_raise ArgumentError + end + + it "raises argument error if you input a negative number for the planet's distance from the Sun" do + expect { + Planet.new('Mars', 'red', 6.4171e23, -2, 'Mars has two moons called Phobos and Deimos') + }.must_raise ArgumentError + end + + it "raises argument error if you input 0 for the planet's distance from the Sun" do + expect { + Planet.new('Mars', 'red', 6.4171e23, 0, 'Mars has two moons called Phobos and Deimos') + }.must_raise ArgumentError + end +end + +describe "solar_system class" do + it "returns a list of type String of planets orbitting the star" do + + earth = Planet.new('Earth', 'blue-green', 5.972e24, 1.496e8, 'Only planet known to support life') + mars = Planet.new('Mars', 'red', 6.4171e23, 2.29e8, 'Mars has two moons called Phobos and Deimos') + sun = SolarSystem.new("Sun") + sun.add_planet(earth) + sun.add_planet(mars) + + expect(sun.list_planets).must_be_instance_of String + end +end +