From 5ed26f187d40bb3096f45d7952e8a59434e95c67 Mon Sep 17 00:00:00 2001 From: noahpatterson Date: Sat, 25 Jan 2014 18:39:51 -0500 Subject: [PATCH 1/4] panda level --- Gemfile.lock | 40 ++++++++++++++++----------- lib/place.rb | 9 ++++--- lib/sales_person.rb | 17 +++++++++++- salesperson.rb | 14 ++++++---- spec/calculates_route_spec.rb | 1 + spec/map_spec.rb | 9 ++++--- spec/place_spec.rb | 33 ++++++++++++++++------- spec/sales_person_spec.rb | 51 ++++++++++++++++++++++++++--------- spec/spec_helper.rb | 15 +++++++++++ 9 files changed, 138 insertions(+), 51 deletions(-) create mode 100644 spec/spec_helper.rb diff --git a/Gemfile.lock b/Gemfile.lock index 28827b4..61e4080 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,30 @@ GEM remote: https://rubygems.org/ specs: - activesupport (3.2.3) - i18n (~> 0.6) - multi_json (~> 1.0) - diff-lcs (1.1.3) - geocoder (1.1.1) - i18n (0.6.0) - multi_json (1.3.4) - rake (0.9.2.2) - rspec (2.10.0) - rspec-core (~> 2.10.0) - rspec-expectations (~> 2.10.0) - rspec-mocks (~> 2.10.0) - rspec-core (2.10.0) - rspec-expectations (2.10.0) - diff-lcs (~> 1.1.3) - rspec-mocks (2.10.1) + activesupport (4.0.2) + i18n (~> 0.6, >= 0.6.4) + minitest (~> 4.2) + multi_json (~> 1.3) + thread_safe (~> 0.1) + tzinfo (~> 0.3.37) + atomic (1.1.14) + diff-lcs (1.2.5) + geocoder (1.1.9) + i18n (0.6.9) + minitest (4.7.5) + multi_json (1.8.4) + rake (10.1.1) + rspec (2.14.1) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) + rspec-core (2.14.7) + rspec-expectations (2.14.4) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.14.4) + thread_safe (0.1.3) + atomic + tzinfo (0.3.38) PLATFORMS ruby diff --git a/lib/place.rb b/lib/place.rb index 99eaadf..bcae5db 100644 --- a/lib/place.rb +++ b/lib/place.rb @@ -1,13 +1,14 @@ require_relative "./map" class Place - attr_accessor :name, :coordinates + attr_accessor :address, :coordinates, :name - def self.build(name) - results = Map.search(name) + def self.build(address, options= {}) + results = Map.search(address) Place.new.tap do |p| - p.name = name + p.address = address p.coordinates = results.coordinates + p.name = options[:name].nil? ? address : options[:name] end end diff --git a/lib/sales_person.rb b/lib/sales_person.rb index d0c2890..018f357 100644 --- a/lib/sales_person.rb +++ b/lib/sales_person.rb @@ -1,6 +1,9 @@ +require_relative 'place' + class SalesPerson attr_reader :cities + def initialize @cities = [] end @@ -9,7 +12,19 @@ def schedule_city(city) @cities << city unless @cities.include?(city) end - def route + def route(starting_point_name = nil) + move_starting_point(starting_point_name) if starting_point_name CalculatesRoute.calculate(cities) end + + private + + def find_starting_point(starting_point_name) + @cities.bsearch {|place| place.name.downcase == starting_point_name.downcase } + end + + def move_starting_point(starting_point_name) + starting_point = find_starting_point(starting_point_name) + @cities.unshift(@cities.delete(starting_point)) + end end diff --git a/salesperson.rb b/salesperson.rb index 9cafbd7..edceb87 100644 --- a/salesperson.rb +++ b/salesperson.rb @@ -2,9 +2,13 @@ phil = SalesPerson.new -phil.schedule_city(Place.build("Dallas, TX")) -phil.schedule_city(Place.build("El Paso, TX")) -phil.schedule_city(Place.build("Austin, TX")) -phil.schedule_city(Place.build("Lubbock, TX")) +phil.schedule_city(Place.build("3900 16th st nw, DC", name: "Home")) +phil.schedule_city(Place.build("3505 Connecticut Ave, DC", name: "Petco")) +phil.schedule_city(Place.build("1250 24th st nw, DC", name: "Work")) +phil.schedule_city(Place.build("3100 14th St NW, DC", name: "Target")) +phil.schedule_city(Place.build("1440 P St NW, DC", name: "Whole Foods")) -puts phil.route + + +# puts "This is the route from home: #{phil.route}" +puts phil.route("Work") diff --git a/spec/calculates_route_spec.rb b/spec/calculates_route_spec.rb index 47679d6..9f9e68e 100644 --- a/spec/calculates_route_spec.rb +++ b/spec/calculates_route_spec.rb @@ -1,3 +1,4 @@ +require_relative "spec_helper" require_relative "../lib/calculates_route" require_relative "../lib/place" diff --git a/spec/map_spec.rb b/spec/map_spec.rb index 2e2f6f1..32406af 100644 --- a/spec/map_spec.rb +++ b/spec/map_spec.rb @@ -1,3 +1,4 @@ +require_relative "spec_helper" require_relative "../lib/map" require 'geocoder' @@ -10,8 +11,8 @@ end it "should use the first item in the array" do - austin = stub("Austin") - dallas = stub("Dallas") + austin = double("Austin") + dallas = double("Dallas") Geocoder.stub(:search) {[austin, dallas]} Map.search("austin, tx").should eq(austin) end @@ -19,8 +20,8 @@ describe ":distance" do it "should calculate distance between two sets of coordinates" do - alpha = stub - beta = stub + alpha = double + beta = double Geocoder::Calculations.should_receive(:distance_between).with(alpha, beta) Map.distance_between(alpha, beta) end diff --git a/spec/place_spec.rb b/spec/place_spec.rb index 7d48250..c017cd7 100644 --- a/spec/place_spec.rb +++ b/spec/place_spec.rb @@ -1,34 +1,49 @@ +require_relative "spec_helper" require_relative "../lib/place" require_relative "../lib/map" describe Place do - it "should have a name" do - subject.should respond_to(:name) + it "should have a address" do + subject.should respond_to(:address) end + it "should have a coordinates" do subject.coordinates = [29,-95] subject.coordinates.should eq([29,-95]) end + it "should have a pretty name" do + subject.should respond_to(:name) + end + describe ":build" do - let(:name) { "El Paso, TX"} - let(:result) { stub("el paso", coordinates: [29, -95])} + let(:address) { "El Paso, TX"} + let(:result) { double("el paso", coordinates: [29, -95])} + let(:name) {"El Paso"} + + it "should return the pretty name if included" do + expect(Place.build(address, name: name).name).to eq("El Paso") + end + + it "should return the address as name if pretty name isn't included" do + expect(Place.build(address).name).to eq("El Paso, TX") + end it "should build from the map" do - Map.should_receive(:search).with(name).and_return(result) - Place.build(name) + Map.should_receive(:search).with(address).and_return(result) + Place.build(address) end it "should be place" do - Map.stub(:search).with(name).and_return(result) - Place.build(name).should be_a(Place) + Map.stub(:search).with(address).and_return(result) + Place.build(address).should be_a(Place) end end describe "#to_s" do - it "should use the city as the to_s" do + it "should use the name as the to_s" do subject.stub(:name) { "Boston" } subject.to_s.should eq("Boston") end diff --git a/spec/sales_person_spec.rb b/spec/sales_person_spec.rb index 08a6ce9..68fb1db 100644 --- a/spec/sales_person_spec.rb +++ b/spec/sales_person_spec.rb @@ -1,30 +1,57 @@ +require_relative "spec_helper" require_relative "../lib/sales_person" require_relative "../lib/calculates_route" +require_relative "../lib/place" describe SalesPerson do + + let(:city1) {Place.build("3505 Connecticut Ave, DC", name: "Petco")} + let(:city2) {Place.build("3900 16th st nw, DC", name: "Home")} + + it "should have many cities" do - city = stub + city = double subject.schedule_city(city) subject.cities.should include(city) end it "should keep the cities only scheduled once" do - city = stub + city = double expect{ subject.schedule_city(city) subject.schedule_city(city) }.to change(subject.cities,:count).by(1) end - it "should calculate a route via the CalculatesRoute" do - cities = [stub, stub, stub] - subject.stub(:cities) { cities } - CalculatesRoute.should_receive(:calculate).with(cities) - subject.route - end - it "should returns the route from CalculatesRoute" do - route_stub = [stub, stub] - CalculatesRoute.stub(:calculate) { route_stub } - subject.route.should eq(route_stub) + describe "#route" do + + + it "should calculate a route via the CalculatesRoute" do + cities = [double, double, double] + subject.stub(:cities) { cities } + CalculatesRoute.should_receive(:calculate).with(cities) + subject.route + end + + it "should returns the route from CalculatesRoute" do + route_stub = [double, double] + CalculatesRoute.stub(:calculate) { route_stub } + subject.route.should eq(route_stub) + end + + it "should be able to add a starting city by name" do + subject.schedule_city(city1) + subject.schedule_city(city2) + starting_point = "home" + expect(subject.route(starting_point)[0]).to eq(city2) + end + + it "should use first city if a starting city wasn't specified" do + subject.schedule_city(city1) + subject.schedule_city(city2) + expect(subject.route[0]).to eq(city1) + end + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..92d360b --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,15 @@ +require 'rspec' +require 'bundler/setup' + + +RSpec.configure do |config| + # Use color in STDOUT + config.color_enabled = true + + # Use color not only in STDOUT but also in pagers and files + config.tty = true + + # Use the specified formatter + config.formatter = :documentation # :progress, :html, :textmate +end + From 6880cb0f0ba5a77743e1cee56f6d9bd0ca2831fe Mon Sep 17 00:00:00 2001 From: noahpatterson Date: Sat, 25 Jan 2014 19:41:00 -0500 Subject: [PATCH 2/4] tiger level --- salesperson.rb | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/salesperson.rb b/salesperson.rb index edceb87..aacaa37 100644 --- a/salesperson.rb +++ b/salesperson.rb @@ -1,14 +1,46 @@ -Dir["./lib/*.rb"].each {|file| require file } +require 'benchmark' +Dir["./lib/*.rb"].each {|file| require file } -phil = SalesPerson.new -phil.schedule_city(Place.build("3900 16th st nw, DC", name: "Home")) -phil.schedule_city(Place.build("3505 Connecticut Ave, DC", name: "Petco")) -phil.schedule_city(Place.build("1250 24th st nw, DC", name: "Work")) -phil.schedule_city(Place.build("3100 14th St NW, DC", name: "Target")) -phil.schedule_city(Place.build("1440 P St NW, DC", name: "Whole Foods")) +@all_cities = ["Abilene", "Alamo", "Alamo Heights", "Alice", "Allen", "Alpine", "Alvarado", "Alvin", "Amarillo", "Andrews", "Angleton", "Argyle", "Arlington", "Austin", "Azle", "Balch Springs", "Bastrop", "Bay City", "Baytown", "Beaumont", "Bellaire", "Belton", "Benbrook", "Big Spring", "Boerne", "Brenham", "Bridgeport", "Brownfield", "Brownsville", "Brownwood", "Bryan", "Bulverde", "Burkburnett", "Burleson", "Burnet", "Canyon", "Carrollton", "Carthage", "Cedar Hill", "Cedar Park", "Cleburne", "Clute", "College Station", "Colleyville", "Columbus", "Conroe", "Converse", "Coppell", "Copperas Cove", "Corinth", "Corpus Christi", "Corsicana", "Crockett", "Crowley", "Dallas", "Deer Park", "Del Rio", "Denison", "Denton", "Desoto", "Devine", "Dickinson", "Donna", "Dumas", "Duncanville", "Eagle Pass", "Edinburg", "El Campo", "El Paso", "Ennis", "Euless", "Farmers Branch", "Flower Mound", "Fort Stockton", "Fort Worth", "Fredericksburg", "Freeport", "Friendswood", "Frisco", "Gainesville", "Galveston", "Garden Ridge", "Garland", "Gatesville", "Georgetown", "Gonzales", "Granbury", "Grand Prairie", "Granite Shoals", "Grapevine", "Greenville", "Haltom City", "Hamilton", "Harker Heights", "Harlingen", "Hearne", "Henderson", "Hewitt", "Highland Park", "Highland Village", "Houston", "Humble", "Hunters Creek Village", "Huntsville", "Hurst", "Irving", "Jacksonville", "Jasper", "Jersey Village", "Katy", "Keller", "Kemah", "Kennedale", "Kerrville", "Killeen", "Kingsville", "Krum", "Kyle", "La Grange", "La Porte", "Lacy Lakeview", "Lago Vista", "Lake Jackson", "Lakeway", "Lamesa", "Lampasas", "Lancaster", "Laredo", "League City", "Leander", "Leon Valley", "Levelland", "Lewisville", "Littlefield", "Live Oak", "Lockhart", "Longview", "Lowry Crossing", "Lubbock", "Lucas", "Lufkin", "Mansfield", "Manvel", "Marble Falls", "Marshall", "McAllen", "McKinney", "Mesquite", "Midland", "Midlothian", "Mission", "Missouri City", "Mount Pleasant", "Muleshoe", "Murphy", "Nacogdoches", "Nassau Bay", "New Braunfels", "Newark", "Newton", "North Richland Hills", "Oak Ridge North", "Odessa", "Orange", "Overton", "Palacios", "Palestine", "Pampa", "Paris", "Pasadena", "Pearland", "Perryton", "Pflugerville", "Plainview", "Plano", "Port Aransas", "Port Arthur", "Port Lavaca", "Portland", "Richardson", "Richland Hills", "Ridge City", "Rio Grande City", "River Oaks", "Rockport", "Rockwall", "Rosenberg", "Round Rock", "Rowlett", "Royse City", "Rusk", "Sachse", "Saginaw", "San Angelo", "San Antonio", "San Benito", "San Marcos", "San Saba", "Santa Fe", "Schertz", "Seabrook", "Sealy", "Seguin", "Selma", "Seymour", "Shenandoah", "Sherman", "Smithville", "Snyder", "Socorro", "Sonora", "Southlake", "Southside Place", "Spring Valley", "Stafford", "Stephenville", "Sugar Land", "Sulphur Springs", "Sweeny", "Tahoka", "Taylor", "Temple", "Terrell", "Texarkana", "Texas City", "The Colony", "The Woodlands", "Tomball", "Tyler", "Universal City", "University Park", "Victoria", "Waco", "Watauga", "Waxahachie", "Weatherford", "Webster", "Weslaco", "West Columbia", "West Lake Hills", "West Orange", "West University Place", "Weston", "Wharton", "White Settlement", "Wichita Falls", "Willow Park", "Windcrest", "Woodway", "Wylie", "Yoakum"] +def personal_route + phil = SalesPerson.new + phil.schedule_city(Place.build("3900 16th st nw, DC", name: "Home")) + phil.schedule_city(Place.build("3505 Connecticut Ave, DC", name: "Petco")) + phil.schedule_city(Place.build("1250 24th st nw, DC", name: "Work")) + phil.schedule_city(Place.build("3100 14th St NW, DC", name: "Target")) + phil.schedule_city(Place.build("1440 P St NW, DC", name: "Whole Foods")) + puts phil.route("Work") +end # puts "This is the route from home: #{phil.route}" -puts phil.route("Work") + +def load_cities(num_cities, sales_person) + times = 0 + until times == num_cities do + @all_cities.shuffle.take(1).each do |city| + sales_person.schedule_city(Place.build("#{city}, TX")) + end + times +=1 + sleep(2) + end +end + +def Benchmark(num_cities) + phil = SalesPerson.new + load_cities(num_cities,phil) + Benchmark.bm do |x| + x.report do + phil.route + end + end +end + +# puts "This is my personal route #{personal_route}" +# puts "This is the benchmark for 2 cities:\n#{Benchmark(2)}" +# puts "This is the benchmark for 10 cities:\n#{Benchmark(10)}" +# puts "This is the benchmark for 50 cities:\n#{Benchmark(50)}" +# puts "This is the benchmark for 2 cities:\n#{Benchmark(200)}" + From 5fc48365f1c9f5b6a7e7e36576c8b4df1c0b1b1d Mon Sep 17 00:00:00 2001 From: noahpatterson Date: Sun, 26 Jan 2014 10:19:19 -0500 Subject: [PATCH 3/4] eagle level --- lib/calculates_route.rb | 11 +++---- lib/sales_person.rb | 8 ++++++ salesperson.rb | 20 ++++++++++--- spec/calculates_route_spec.rb | 18 ++++++++---- spec/sales_person_spec.rb | 35 ++++++++++++++++------- spec/spec_helper.rb | 54 +++++++++++++++++++++++++++++++++++ 6 files changed, 120 insertions(+), 26 deletions(-) diff --git a/lib/calculates_route.rb b/lib/calculates_route.rb index 4488393..b056fc7 100644 --- a/lib/calculates_route.rb +++ b/lib/calculates_route.rb @@ -1,13 +1,13 @@ class CalculatesRoute def self.calculate(points) - remaining_points = points route = [] - route << remaining_points.slice!(0) + route << {point: remaining_points.slice!(0), distance: 0} until remaining_points == [] do - next_point = shortest_distance(route.last, remaining_points) - route << remaining_points.slice!(remaining_points.index(next_point)) + next_point = shortest_distance(route.last.fetch(:point), remaining_points) + remaining_points.delete(next_point.fetch(:point)) + route << next_point end route end @@ -16,7 +16,8 @@ def self.shortest_distance(from, possible) distances = possible.map do |point| {point: point, distance: Map.distance_between(from, point)} end - distances.sort{|a,b| a.fetch(:distance) <=> b.fetch(:distance)}.first.fetch(:point) + sorted = distances.sort{|a,b| a.fetch(:distance) <=> b.fetch(:distance)} + sorted.first end end diff --git a/lib/sales_person.rb b/lib/sales_person.rb index 018f357..da9b644 100644 --- a/lib/sales_person.rb +++ b/lib/sales_person.rb @@ -17,6 +17,14 @@ def route(starting_point_name = nil) CalculatesRoute.calculate(cities) end + def calculate_total_miles(route) + route.map {|leg| leg.fetch(:distance)}.reduce(:+) + end + + def calculate_traveling_time(total_miles) + total_miles/55 + end + private def find_starting_point(starting_point_name) diff --git a/salesperson.rb b/salesperson.rb index aacaa37..8d9854f 100644 --- a/salesperson.rb +++ b/salesperson.rb @@ -4,15 +4,14 @@ @all_cities = ["Abilene", "Alamo", "Alamo Heights", "Alice", "Allen", "Alpine", "Alvarado", "Alvin", "Amarillo", "Andrews", "Angleton", "Argyle", "Arlington", "Austin", "Azle", "Balch Springs", "Bastrop", "Bay City", "Baytown", "Beaumont", "Bellaire", "Belton", "Benbrook", "Big Spring", "Boerne", "Brenham", "Bridgeport", "Brownfield", "Brownsville", "Brownwood", "Bryan", "Bulverde", "Burkburnett", "Burleson", "Burnet", "Canyon", "Carrollton", "Carthage", "Cedar Hill", "Cedar Park", "Cleburne", "Clute", "College Station", "Colleyville", "Columbus", "Conroe", "Converse", "Coppell", "Copperas Cove", "Corinth", "Corpus Christi", "Corsicana", "Crockett", "Crowley", "Dallas", "Deer Park", "Del Rio", "Denison", "Denton", "Desoto", "Devine", "Dickinson", "Donna", "Dumas", "Duncanville", "Eagle Pass", "Edinburg", "El Campo", "El Paso", "Ennis", "Euless", "Farmers Branch", "Flower Mound", "Fort Stockton", "Fort Worth", "Fredericksburg", "Freeport", "Friendswood", "Frisco", "Gainesville", "Galveston", "Garden Ridge", "Garland", "Gatesville", "Georgetown", "Gonzales", "Granbury", "Grand Prairie", "Granite Shoals", "Grapevine", "Greenville", "Haltom City", "Hamilton", "Harker Heights", "Harlingen", "Hearne", "Henderson", "Hewitt", "Highland Park", "Highland Village", "Houston", "Humble", "Hunters Creek Village", "Huntsville", "Hurst", "Irving", "Jacksonville", "Jasper", "Jersey Village", "Katy", "Keller", "Kemah", "Kennedale", "Kerrville", "Killeen", "Kingsville", "Krum", "Kyle", "La Grange", "La Porte", "Lacy Lakeview", "Lago Vista", "Lake Jackson", "Lakeway", "Lamesa", "Lampasas", "Lancaster", "Laredo", "League City", "Leander", "Leon Valley", "Levelland", "Lewisville", "Littlefield", "Live Oak", "Lockhart", "Longview", "Lowry Crossing", "Lubbock", "Lucas", "Lufkin", "Mansfield", "Manvel", "Marble Falls", "Marshall", "McAllen", "McKinney", "Mesquite", "Midland", "Midlothian", "Mission", "Missouri City", "Mount Pleasant", "Muleshoe", "Murphy", "Nacogdoches", "Nassau Bay", "New Braunfels", "Newark", "Newton", "North Richland Hills", "Oak Ridge North", "Odessa", "Orange", "Overton", "Palacios", "Palestine", "Pampa", "Paris", "Pasadena", "Pearland", "Perryton", "Pflugerville", "Plainview", "Plano", "Port Aransas", "Port Arthur", "Port Lavaca", "Portland", "Richardson", "Richland Hills", "Ridge City", "Rio Grande City", "River Oaks", "Rockport", "Rockwall", "Rosenberg", "Round Rock", "Rowlett", "Royse City", "Rusk", "Sachse", "Saginaw", "San Angelo", "San Antonio", "San Benito", "San Marcos", "San Saba", "Santa Fe", "Schertz", "Seabrook", "Sealy", "Seguin", "Selma", "Seymour", "Shenandoah", "Sherman", "Smithville", "Snyder", "Socorro", "Sonora", "Southlake", "Southside Place", "Spring Valley", "Stafford", "Stephenville", "Sugar Land", "Sulphur Springs", "Sweeny", "Tahoka", "Taylor", "Temple", "Terrell", "Texarkana", "Texas City", "The Colony", "The Woodlands", "Tomball", "Tyler", "Universal City", "University Park", "Victoria", "Waco", "Watauga", "Waxahachie", "Weatherford", "Webster", "Weslaco", "West Columbia", "West Lake Hills", "West Orange", "West University Place", "Weston", "Wharton", "White Settlement", "Wichita Falls", "Willow Park", "Windcrest", "Woodway", "Wylie", "Yoakum"] - -def personal_route phil = SalesPerson.new +def personal_route(phil) phil.schedule_city(Place.build("3900 16th st nw, DC", name: "Home")) phil.schedule_city(Place.build("3505 Connecticut Ave, DC", name: "Petco")) phil.schedule_city(Place.build("1250 24th st nw, DC", name: "Work")) phil.schedule_city(Place.build("3100 14th St NW, DC", name: "Target")) phil.schedule_city(Place.build("1440 P St NW, DC", name: "Whole Foods")) - puts phil.route("Work") + phil.route("Work") end # puts "This is the route from home: #{phil.route}" @@ -38,9 +37,22 @@ def Benchmark(num_cities) end end -# puts "This is my personal route #{personal_route}" +def pretty_time(seconds) + mm, ss = seconds.divmod(60) #=> [4515, 21] + hh, mm = mm.divmod(60) #=> [75, 15] + dd, hh = hh.divmod(24) #=> [3, 3] + "%d days, %d hours, %d minutes and %d seconds" % [dd, hh, mm, ss] +end + +route = personal_route(phil) +puts "This is my personal route: #{route.map {|leg| leg.fetch(:point).name}}" +miles = phil.calculate_total_miles(route) +puts "Phil traveled #{miles} miles" +time = phil.calculate_traveling_time(miles)*60*60 +puts "It took phil #{pretty_time(time)}" # puts "This is the benchmark for 2 cities:\n#{Benchmark(2)}" # puts "This is the benchmark for 10 cities:\n#{Benchmark(10)}" # puts "This is the benchmark for 50 cities:\n#{Benchmark(50)}" # puts "This is the benchmark for 2 cities:\n#{Benchmark(200)}" + diff --git a/spec/calculates_route_spec.rb b/spec/calculates_route_spec.rb index 9f9e68e..6157dd8 100644 --- a/spec/calculates_route_spec.rb +++ b/spec/calculates_route_spec.rb @@ -3,14 +3,20 @@ require_relative "../lib/place" describe CalculatesRoute do - let(:dallas) {Place.build("Dallas, TX") } - let(:austin ) { Place.build("Austin, TX")} - let(:lubbock ) { Place.build("Lubbock, TX")} - let(:el_paso ) { Place.build("El Paso, TX")} + let(:dallas ) { Place.build("Dallas, TX") } + let(:austin ) { Place.build("Austin, TX") } + let(:lubbock ) { Place.build("Lubbock, TX") } + let(:el_paso ) { Place.build("El Paso, TX") } + let(:points ) { [dallas, el_paso, austin, lubbock] } it "should calculate the route" do - points = [dallas, el_paso, austin, lubbock] expected = [dallas, austin, lubbock, el_paso] - CalculatesRoute.calculate(points).should eq(expected) + route = CalculatesRoute.calculate(points) + route.map {|leg| leg.fetch(:point)}.should eq(expected) end + + it "should also output the distance of each leg" do + CalculatesRoute.calculate(points)[0].fetch(:distance).should eq(0) + end + end diff --git a/spec/sales_person_spec.rb b/spec/sales_person_spec.rb index 68fb1db..1b0ca77 100644 --- a/spec/sales_person_spec.rb +++ b/spec/sales_person_spec.rb @@ -7,27 +7,25 @@ let(:city1) {Place.build("3505 Connecticut Ave, DC", name: "Petco")} let(:city2) {Place.build("3900 16th st nw, DC", name: "Home")} + let(:city) {double} + let(:scheduled) { subject.schedule_city(city) } it "should have many cities" do - city = double - subject.schedule_city(city) + scheduled subject.cities.should include(city) end it "should keep the cities only scheduled once" do - city = double expect{ - subject.schedule_city(city) - subject.schedule_city(city) + scheduled + scheduled }.to change(subject.cities,:count).by(1) end describe "#route" do - - it "should calculate a route via the CalculatesRoute" do - cities = [double, double, double] + cities = [Place, double, double] subject.stub(:cities) { cities } CalculatesRoute.should_receive(:calculate).with(cities) subject.route @@ -43,15 +41,30 @@ subject.schedule_city(city1) subject.schedule_city(city2) starting_point = "home" - expect(subject.route(starting_point)[0]).to eq(city2) + first_route_point = subject.route(starting_point)[0] + expect(first_route_point.fetch(:point)).to eq(city2) end it "should use first city if a starting city wasn't specified" do subject.schedule_city(city1) subject.schedule_city(city2) - expect(subject.route[0]).to eq(city1) + first_route_point = subject.route[0] + expect(first_route_point.fetch(:point)).to eq(city1) + end + end + + describe "#calculate_total_miles" do + it "should report the total miles traveled on the route" do + route = [{point: city1, distance: 0}, {point: city2, distance: 1.1}] + expect(subject.calculate_total_miles(route)).to eq(1.1) + end + end + + describe "#calculate_traveling_time" do + it "shoudld report the traveling time of the route" do + total_miles = 200 + expect(subject.calculate_traveling_time(total_miles)).to eq(200/55) end - end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 92d360b..5a2dea5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ require 'rspec' require 'bundler/setup' +require 'geocoder' RSpec.configure do |config| @@ -13,3 +14,56 @@ config.formatter = :documentation # :progress, :html, :textmate end +Geocoder.configure(:lookup => :test) + +Geocoder::Lookup::Test.add_stub( + "3505 Connecticut Ave, DC", [ + { + 'latitude' => 38.935838, + 'longitude' => -77.05994108029152 + } + ] +) +Geocoder::Lookup::Test.add_stub( + "3900 16th st nw, DC", [ + { + 'latitude' => 38.939297, + 'longitude' => -77.037307 + } + ] +) + +#texas +Geocoder::Lookup::Test.add_stub( + "Dallas, TX", [ + { + 'latitude' => 32.7801399, + 'longitude' => -96.80045109999999 + } + ] +) +Geocoder::Lookup::Test.add_stub( + "Austin, TX", [ + { + 'latitude' => 30.267153, + 'longitude' => -97.7430608, + } + ] +) +Geocoder::Lookup::Test.add_stub( + "Lubbock, TX", [ + { + 'latitude' => 33.70845389999999, + 'longitude' => -101.748554, + } + ] +) +Geocoder::Lookup::Test.add_stub( + "El Paso, TX", [ + { + 'latitude' => 31.7699559, + 'longitude' => -106.4968055, + } + ] +) + From b27d38cea8097386d9ce8cb5f95d919f15e23058 Mon Sep 17 00:00:00 2001 From: noahpatterson Date: Sun, 26 Jan 2014 10:30:48 -0500 Subject: [PATCH 4/4] add speed change to time_traveled --- lib/sales_person.rb | 4 ++-- salesperson.rb | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/sales_person.rb b/lib/sales_person.rb index da9b644..f52c03d 100644 --- a/lib/sales_person.rb +++ b/lib/sales_person.rb @@ -21,8 +21,8 @@ def calculate_total_miles(route) route.map {|leg| leg.fetch(:distance)}.reduce(:+) end - def calculate_traveling_time(total_miles) - total_miles/55 + def calculate_traveling_time(total_miles, speed = 55) + total_miles/speed end private diff --git a/salesperson.rb b/salesperson.rb index 8d9854f..1be7ca1 100644 --- a/salesperson.rb +++ b/salesperson.rb @@ -45,10 +45,11 @@ def pretty_time(seconds) end route = personal_route(phil) +puts route puts "This is my personal route: #{route.map {|leg| leg.fetch(:point).name}}" miles = phil.calculate_total_miles(route) puts "Phil traveled #{miles} miles" -time = phil.calculate_traveling_time(miles)*60*60 +time = phil.calculate_traveling_time(miles, 25)*60*60 puts "It took phil #{pretty_time(time)}" # puts "This is the benchmark for 2 cities:\n#{Benchmark(2)}" # puts "This is the benchmark for 10 cities:\n#{Benchmark(10)}"