Skip to content

Commit

Permalink
refactor tests and all_paths.rb
Browse files Browse the repository at this point in the history
  • Loading branch information
gitlaura committed Jul 24, 2014
1 parent a1cd04f commit c8b3b99
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 158 deletions.
208 changes: 83 additions & 125 deletions lib/all_paths.rb
@@ -1,135 +1,93 @@
require 'ostruct'

class AllPaths

def initialize(flights, departure_city, arrival_city)
@flights = flights
@departure_city = departure_city
@arrival_city = arrival_city
@final_paths = []
end

def create_paths
from_city_groups = group_flights_by_from_city
from_city_groups[@departure_city.to_sym].each do |flight_from_dep_city|
if flight_from_dep_city.to == @arrival_city
@final_paths << flight_from_dep_city
else
@current_path = create_new_path(flight_from_dep_city)
reset_price(flight_from_dep_city)
reset_arrivals(flight_from_dep_city)
reset_arrival_cities(flight_from_dep_city)
update_current_path(flight_from_dep_city.to, from_city_groups)
end
def initialize(flights, departure_city, arrival_city)
@flights = flights
@departure_city = departure_city
@arrival_city = arrival_city
@final_paths = []
end

def create_paths
@departure_city_groups = group_flights_by_departure_city
@departure_city_groups[@departure_city.to_sym].each do |flight_from_dep_city|
if flight_from_dep_city.to == @arrival_city
@final_paths << flight_from_dep_city
else
@current_path = create_new_path(flight_from_dep_city)
@path_attributes = reset_path_attributes(flight_from_dep_city)
update_current_path
end
@final_paths
end

def group_flights_by_from_city
from_city_groups = {}
@flights.each do |flight|
new_from = flight.from.to_sym
from_city_groups[new_from] = [] if from_city_groups[new_from].nil?
from_city_groups[new_from] << flight
@final_paths
end

def group_flights_by_departure_city
departure_city_groups = {}
@flights.each do |flight|
new_from = flight.from.to_sym
departure_city_groups[new_from] ||= []
departure_city_groups[new_from] << flight
end
departure_city_groups
end

def create_new_path(flight)
OpenStruct.new(:from => @departure_city, :to => nil, :dep => flight.dep, :arr => nil, :price => nil)
end

def reset_path_attributes(flight)
path_attributes = {}
path_attributes[:prices], path_attributes[:arrival_times], path_attributes[:arrival_cities] = [], [], []
path_attributes[:prices] << flight.price
path_attributes[:arrival_times] << flight.arr
path_attributes[:arrival_cities] << flight.to
path_attributes
end

def update_current_path(new_path_level = false)
new_dep_city = @path_attributes[:arrival_cities].last.to_sym
@departure_city_groups[new_dep_city].each do |possible_flight|
if new_path_level == false
remove_attributes_from_last_flight if @path_attributes[:arrival_cities].size > 1
end
from_city_groups
end

private

def create_new_path(flight)
OpenStruct.new(:from => @departure_city, :to => nil, :dep => flight.dep, :arr => nil, :price => nil)
end

def reset_price(flight)
@prices = []
@prices << flight.price
end

def reset_arrivals(flight)
@arrival_times = []
@arrival_times << flight.arr
end

def reset_arrival_cities(flight)
@arrival_cities = []
@arrival_cities << flight.to
end

def update_current_path(current_from_city, from_city_groups, loop = false)
new_from_city = current_from_city.to_sym
from_city_groups[new_from_city].each do |possible_flight|
if loop == false
reset_to_price_from_city if @prices.size > 1
reset_arrivals_from_city if @arrival_times.size > 1
reset_arrival_cities_from_city if @arrival_cities.size > 1
end
if valid_next_flight?(possible_flight)
#update_path(possible_flight)
update_price(possible_flight)
update_arrivals(possible_flight)
update_arrival_cities(possible_flight)
if possible_flight.to == @arrival_city
add_prices_to_path
add_arrivals_to_path(possible_flight)
add_arrival_cities_to_path(possible_flight)
reset_to_price_from_city
reset_arrivals_from_city
reset_arrival_cities_from_city
add_current_path_to_final_paths(possible_flight)
next
end
update_current_path(@arrival_cities.last, from_city_groups, true)
if valid_next_flight?(possible_flight)
update_path_attributes(possible_flight)
if possible_flight.to == @arrival_city
add_attributes_to_path
add_current_path_to_final_paths
remove_attributes_from_last_flight
next
end
update_current_path(true)
end
end

def valid_next_flight?(possible_flight)
@arrival_times.last < possible_flight.dep && possible_flight.to > possible_flight.from
end

def update_path(possible_flight)
@current_path.to = possible_flight.to if possible_flight.to != @arrival_city
end

def update_price(possible_flight)
@prices << possible_flight.price
end

def update_arrivals(possible_flight)
@arrival_times << possible_flight.arr
end

def update_arrival_cities(possible_flight)
@arrival_cities << possible_flight.to
end

def add_prices_to_path
@current_path.price = @prices.reduce(:+)
end

def add_arrivals_to_path(possible_flight)
@current_path.arr = @arrival_times.last
end

def add_arrival_cities_to_path(possible_flight)
@current_path.to = @arrival_cities.last
end

def reset_to_price_from_city
@prices.pop
end

def reset_arrivals_from_city
@arrival_times.pop
end

def reset_arrival_cities_from_city
@arrival_cities.pop
end

def add_current_path_to_final_paths(possible_flight)
end_path = @current_path.dup
@final_paths << end_path
end
end

def valid_next_flight?(possible_flight)
@path_attributes[:arrival_times].last < possible_flight.dep && possible_flight.to > possible_flight.from
end

def update_path_attributes(possible_flight)
@path_attributes[:prices] << possible_flight.price
@path_attributes[:arrival_times] << possible_flight.arr
@path_attributes[:arrival_cities] << possible_flight.to
end

def add_attributes_to_path
@current_path.price = @path_attributes[:prices].reduce(:+)
@current_path.arr = @path_attributes[:arrival_times].last
@current_path.to = @path_attributes[:arrival_cities].last
end

def remove_attributes_from_last_flight
@path_attributes[:prices].pop
@path_attributes[:arrival_times].pop
@path_attributes[:arrival_cities].pop
end

def add_current_path_to_final_paths
end_path = @current_path.dup
@final_paths << end_path
end
end
18 changes: 9 additions & 9 deletions lib/best_flights.rb
@@ -1,26 +1,26 @@
class BestFlights
class << self
def get_cheapest_flight(all_flight_paths)
@lowest_price = nil
lowest_price = nil
all_flight_paths.each do |flight|
if @lowest_price.nil? || flight.price < @lowest_price
if lowest_price.nil? || flight.price < lowest_price
@best_flight = flight
@lowest_price = flight.price
elsif @lowest_price == flight.price
lowest_price = flight.price
elsif lowest_price == flight.price
@best_flight = get_fastest_flight([@best_flight, flight])
end
end
@best_flight
end

def get_fastest_flight(all_flight_paths)
@shortest_length = nil
shortest_length = nil
all_flight_paths.each do |flight|
@length = flight.arr - flight.dep
if @shortest_length.nil? || @length < @shortest_length
length = flight.arr - flight.dep
if shortest_length.nil? || length < shortest_length
@best_flight = flight
@shortest_length = @length
elsif @shortest_length == @length
shortest_length = length
elsif shortest_length == length
@best_flight = get_cheapest_flight([@best_flight, flight])
end
end
Expand Down
11 changes: 4 additions & 7 deletions lib/flight_parser.rb
Expand Up @@ -3,8 +3,7 @@
class FlightParser
class << self
def parse(txt_file)
@all_flights = []
@all_cases = []
all_cases = []
flights_created = 0

file = File.open(txt_file).read
Expand All @@ -19,10 +18,10 @@ def parse(txt_file)
from, to, dep, arr, price = line.strip.split(" ")
@new_case << create_flight(from, to, dep, arr, price)
flights_created += 1
@all_cases << @new_case if flights_created == @number_of_flights
all_cases << @new_case if flights_created == @number_of_flights
end
end
@all_cases
all_cases
end

def create_flight(from, to, dep, arr, price)
Expand All @@ -38,9 +37,7 @@ def create_flight(from, to, dep, arr, price)
def to_number(time)
hour, minutes = time.split(":")
hour.to_i * 60 + minutes.to_i
end

private
end

def empty_line?(line, index)
index < 2 || line == "\n"
Expand Down
18 changes: 17 additions & 1 deletion spec/all_paths_spec.rb
Expand Up @@ -20,6 +20,7 @@

let(:departure_city){"A"}
let(:arrival_city){"Z"}
let(:all_paths){AllPaths.new([flight_one, flight_five], departure_city, arrival_city)}

it "gets the correct paths for just two flights" do
all_flights = [flight_one, flight_five]
Expand Down Expand Up @@ -55,8 +56,23 @@
all_flights = [flight_one, flight_two, flight_three, flight_four, flight_five, flight_six, flight_seven, flight_eight]
all_paths_class = AllPaths.new(all_flights, departure_city, arrival_city)

all_froms = all_paths_class.group_flights_by_from_city
all_froms = all_paths_class.group_flights_by_departure_city

expect(all_froms[:A]).to eq([flight_one, flight_two, flight_three])
end

it "creates a new path" do
path = all_paths.create_new_path(flight_one)

expect(path.from).to eq(flight_one.from)
expect(path.to).to eq(nil)
expect(path.dep).to eq(flight_one.dep)
expect(path.arr).to eq(nil)
expect(path.price).to eq(nil)
end

it "resets path attributes" do
path_attributes = all_paths.reset_path_attributes(flight_one)
expect(path_attributes).to eq({:prices =>[50],:arrival_times => [540],:arrival_cities => ["B"]})
end
end
2 changes: 1 addition & 1 deletion spec/best_flights_spec.rb
Expand Up @@ -6,7 +6,7 @@
let(:flight_three){OpenStruct.new(:from => "A", :to => "Z", :dep => 600, :arr => 720, :price => 300.00)}
let(:case_one){[flight_one, flight_two, flight_three]}

it "gets the cheapest flight" do
it "gets the cheapest flight if they're equally cheap" do
best_flight = BestFlights.get_cheapest_flight(case_one)
expect(best_flight).to eq(flight_one)
end
Expand Down
15 changes: 12 additions & 3 deletions spec/flight_formatter_spec.rb
@@ -1,11 +1,20 @@
require 'flight_formatter'

describe "Flight formatter" do
let(:flight_one){OpenStruct.new(:from => "A", :to => "B", :dep => 540, :arr => 600, :price => 100.00)}
let(:flight_two){OpenStruct.new(:from => "B", :to => "Z", :dep => 690, :arr => 810, :price => 100.00)}

it "creates the correct flight format" do
flight_one = OpenStruct.new(:from => "A", :to => "B", :dep => 540, :arr => 600, :price => 100.00)
flight_two = OpenStruct.new(:from => "B", :to => "Z", :dep => 690, :arr => 810, :price => 100.00)

line = FlightFormatter.get_print_format([flight_one, flight_two])

expect(line).to include("9:00 10:00 100.00\n")
end

it "formats the correct time" do
expect(FlightFormatter.format_time(550)).to eq("09:10")
end

it "formats the correct price" do
expect(FlightFormatter.format_price(375.2)).to eq("375.20")
end
end
16 changes: 13 additions & 3 deletions spec/flight_parser_spec.rb
@@ -1,16 +1,16 @@
require 'flight_parser'

describe "Flight parser" do
let(:file){"sample-input.txt"}

it "parses flights" do
cases = FlightParser.parse(file)
cases = FlightParser.parse("sample-input.txt")

expect(cases.size).to eq(2)
expect(cases[0].size).to eq(3)
end

it "creates a flight object" do
new_flight = FlightParser.create_flight("A", "Z", "9:00", "10:00", "100.00")

expect(new_flight.from).to eq("A")
expect(new_flight.to).to eq("Z")
expect(new_flight.dep).to eq(540)
Expand All @@ -21,4 +21,14 @@
number = FlightParser.to_number("9:15")
expect(number).to eq(555)
end

it "checks for empty lines" do
result = FlightParser.empty_line?("\n", 3)
expect(result).to eq(true)
end

it "checks for the case number" do
result = FlightParser.number_of_cases?("5")
expect(result).to eq(true)
end
end

1 comment on commit c8b3b99

@gitlaura
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • refactored all_paths.rb to eliminate duplicate among the methods that update the current path's attributes
  • refactored tests for multiple classes
  • removed "let" in rspec unless reused the variable multiple times

Please sign in to comment.