Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source 'http://rubygems.org'

ruby '2.5.5'
ruby '2.6.5'

gem 'rake'

Expand Down
34 changes: 34 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
GEM
remote: http://rubygems.org/
specs:
ansi (1.5.0)
awesome_print (1.8.0)
builder (3.2.4)
csv (3.1.2)
minitest (5.14.0)
minitest-reporters (1.4.2)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
minitest-skip (0.0.1)
minitest (~> 5.0)
rake (13.0.1)
ruby-progressbar (1.10.1)

PLATFORMS
ruby

DEPENDENCIES
awesome_print
csv
minitest
minitest-reporters
minitest-skip
rake

RUBY VERSION
ruby 2.6.5p114

BUNDLED WITH
2.1.4
1 change: 1 addition & 0 deletions lib/csv_record.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'csv'
require 'time'

module RideShare
class CsvRecord
Expand Down
77 changes: 77 additions & 0 deletions lib/driver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
require_relative 'csv_record'

module RideShare
class Driver < CsvRecord

attr_reader :id, :name, :vin, :status, :trips

def initialize(id: nil, name: nil, vin:, status: :AVAILABLE, trips: nil)
super(id)

@name = name
@vin = vin
@status = status
@trips = trips || []

unless @status == :AVAILABLE || @status == :UNAVAILABLE
raise ArgumentError.new("#{@status} is not a valid status.")
end

unless @vin.split(//).length == 17
raise ArgumentError.new("#{@vin} is not a valid VIN number.")
end

end

def add_trip(trip)
unless trip.end_time == nil
@trips << trip
end
end

def average_rating
ratings = []
if @trips.length == 0
return 0
end

@trips.each do |trip|

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider using a .map

unless trip.end_time == nil
ratings << trip.rating
end
end

return (ratings.sum.to_f / ratings.length.to_f)
end

def total_revenue
total_revenue = 0
total_revenue = @trips.sum {
|trip| unless trip.cost == nil
trip.cost
end
}
return total_revenue
end

def change_driver_status
if @status == :AVAILABLE
@status = :UNAVAILABLE
else
@status = :AVAILABLE
end
end

private

def self.from_csv(record)
return new(
id: record[:id],
name: record[:name],
vin: record[:vin],
status: record[:status].to_sym
)
end

end
end
21 changes: 20 additions & 1 deletion lib/passenger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module RideShare
class Passenger < CsvRecord
attr_reader :name, :phone_number, :trips

def initialize(id:, name:, phone_number:, trips: nil)
def initialize(id:, name:, phone_number:, trips: [])
super(id)

@name = name
Expand All @@ -16,6 +16,25 @@ def add_trip(trip)
@trips << trip
end

def net_expenditures
total_cost = 0
total_cost = @trips.sum {
|trip| unless trip.cost == nil
trip.cost
end
}
return total_cost
end

def total_time_spent
total_time = @trips.sum {
|trip| unless trip.end_time == nil
trip.duration
end
}
return total_time
end

private

def self.from_csv(record)
Expand Down
41 changes: 36 additions & 5 deletions lib/trip.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
require 'csv'

require_relative 'csv_record'
require_relative 'driver'
require_relative 'passenger'

module RideShare
class Trip < CsvRecord
attr_reader :id, :passenger, :passenger_id, :start_time, :end_time, :cost, :rating
attr_reader :id, :passenger, :passenger_id, :start_time, :end_time, :cost, :rating, :driver_id, :driver

def initialize(
id:,
passenger: nil,
passenger_id: nil,
driver_id: nil,
driver: nil,
start_time:,
end_time:,
cost: nil,
rating:
)
super(id)

if driver
@driver = driver
@driver_id = driver.id

elsif driver_id
@driver_id = driver_id

else
raise ArgumentError, 'Driver or driver_id is required'
end

if passenger
@passenger = passenger
@passenger_id = passenger.id
Expand All @@ -33,9 +48,18 @@ def initialize(
@cost = cost
@rating = rating

if @rating > 5 || @rating < 1
valid_ratings = [1, 2, 3, 4, 5, nil]

unless valid_ratings.include?(@rating)
raise ArgumentError.new("Invalid rating #{@rating}")
end

if end_time != nil
if @end_time - @start_time < 0
raise ArgumentError.new("End time: #{@end_time} cannot be less than start time: #{@start_time}")
end
end

end

def inspect
Expand All @@ -46,9 +70,15 @@ def inspect
"PassengerID=#{passenger&.id.inspect}>"
end

def connect(passenger)
def connect(passenger, driver)
@passenger = passenger
@driver = driver
passenger.add_trip(self)
driver.add_trip(self)
end

def duration
return @end_time - @start_time
end

private
Expand All @@ -57,8 +87,9 @@ def self.from_csv(record)
return self.new(
id: record[:id],
passenger_id: record[:passenger_id],
start_time: record[:start_time],
end_time: record[:end_time],
driver_id: record[:driver_id],
start_time: Time.parse(record[:start_time]),
end_time: Time.parse(record[:end_time]),
cost: record[:cost],
rating: record[:rating]
)
Expand Down
53 changes: 52 additions & 1 deletion lib/trip_dispatcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

require_relative 'passenger'
require_relative 'trip'
require_relative 'driver'

module RideShare
class TripDispatcher
Expand All @@ -11,6 +12,7 @@ class TripDispatcher
def initialize(directory: './support')
@passengers = Passenger.load_all(directory: directory)
@trips = Trip.load_all(directory: directory)
@drivers = Driver.load_all(directory: directory)
connect_trips
end

Expand All @@ -19,6 +21,11 @@ def find_passenger(id)
return @passengers.find { |passenger| passenger.id == id }
end

def find_driver(id)
Driver.validate_id(id)
return @drivers.find { |driver| driver.id == id}
end

def inspect
# Make puts output more useful
return "#<#{self.class.name}:0x#{object_id.to_s(16)} \
Expand All @@ -27,12 +34,56 @@ def inspect
#{passengers.count} passengers>"
end

def request_trip(passenger_id)
passenger = self.find_passenger(passenger_id)
trip_id = 601
driver = find_driver_for_trip

trip = RideShare::Trip.new(
id: trip_id,
passenger: passenger,
passenger_id: passenger_id,
start_time: Time.now,
end_time: nil,
cost: nil,
rating: nil,
driver_id: driver.id,
driver: driver
)
driver.change_driver_status
driver.add_trip(trip)
passenger.add_trip(trip)
@trips << trip
trip_id += 1
return trip
end

def find_driver_for_trip

available_drivers = self.drivers.select { |driver| driver.status == :AVAILABLE}

if available_drivers.length == 0
raise ArgumentError.new("There are no available drivers!")
end

available_drivers.each do |driver|
if driver.trips.length == 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is there an enumerable you could use here?

return driver
end
end

available_drivers.sort! { |driver| driver.trips[-1].end_time}

return available_drivers[-1]
end

private

def connect_trips
@trips.each do |trip|
passenger = find_passenger(trip.passenger_id)
trip.connect(passenger)
driver = find_driver(trip.driver_id)
trip.connect(passenger, driver)
end

return trips
Expand Down
38 changes: 36 additions & 2 deletions test/driver_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require_relative 'test_helper'

xdescribe "Driver class" do
describe "Driver class" do
describe "Driver instantiation" do
before do
@driver = RideShare::Driver.new(
Expand Down Expand Up @@ -131,6 +131,40 @@
end

describe "total_revenue" do
# You add tests for the total_revenue method
before do
@driver = RideShare::Driver.new(
id: 54,
name: "Rogers Bartell IV",
vin: "1C9EVBRM0YBC564DZ"
)

trip = RideShare::Trip.new(
id: 8,
driver: @driver,
passenger_id: 3,
start_time: Time.new(2016, 8, 8),
end_time: Time.new(2016, 8, 8),
cost: 2,
rating: 5
)

trip2 = RideShare::Trip.new(
id: 8,
driver: @driver,
passenger_id: 3,
start_time: Time.new(2016, 8, 11),
end_time: Time.new(2016, 8, 12),
cost: 13,
rating: 5
)

@driver.add_trip(trip)
@driver.add_trip(trip2)
end

it "Will return the total revenue for the driver" do
# You add tests for the total_revenue method
expect (@driver.total_revenue).must_equal 15
end
end
end
Loading