-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trang & Daniela - RideShare #5
base: master
Are you sure you want to change the base?
Changes from all commits
48ea89e
0dcb270
43ead54
fb4aa26
cc7d80b
0cb375c
a603454
845d78f
3f53a67
eb1a4db
cb369e4
71766c7
5d70e53
1407316
5b3d0a6
ce6c971
83e9ef5
1da101c
aa88c2d
30cbbcf
2676ef2
fa5d16f
25d5961
43946e3
d90eb63
d85e045
12e4015
3dbdcda
46f4c11
da9ab8f
6639641
d13cc32
216e930
2aa53a8
1350433
7230306
9d724f7
cc05b13
e2b7de4
1937225
26682f2
e2f73fa
d75b2df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
require 'csv' | ||
require 'time' | ||
require 'pry' | ||
|
||
require_relative 'user' | ||
require_relative 'trip' | ||
|
@@ -9,46 +10,71 @@ class TripDispatcher | |
attr_reader :drivers, :passengers, :trips | ||
|
||
def initialize(user_file = 'support/users.csv', | ||
trip_file = 'support/trips.csv') | ||
trip_file = 'support/trips.csv', | ||
driver_file = 'support/drivers.csv') | ||
@passengers = load_users(user_file) | ||
@drivers = load_drivers(driver_file) | ||
@trips = load_trips(trip_file) | ||
end | ||
|
||
def load_users(filename) | ||
users = [] | ||
|
||
CSV.read(filename, headers: true).each do |line| | ||
input_data = {} | ||
input_data[:id] = line[0].to_i | ||
input_data[:name] = line[1] | ||
input_data[:phone] = line[2] | ||
|
||
users << User.new(input_data) | ||
users << User.new({:id => line[0].to_i, :name => line[1], :phone => line[2]}) | ||
end | ||
|
||
return users | ||
end | ||
|
||
def load_drivers(filename) | ||
drivers = [] | ||
|
||
CSV.read(filename, headers: true).each do |line| | ||
found_passenger = find_passenger(line[0].to_i) | ||
|
||
new_driver = Driver.new(id: line[0].to_i, | ||
name: found_passenger.name, | ||
phone: found_passenger.phone_number, | ||
vin: line[1], | ||
status: line[2].to_sym, | ||
trips: found_passenger.trips) | ||
|
||
drivers << new_driver | ||
@passengers[@passengers.index(found_passenger)] = new_driver | ||
end | ||
|
||
return drivers | ||
end | ||
|
||
def find_driver(id) | ||
check_id(id) | ||
return @drivers.find { |driver| driver.id == id } | ||
end | ||
|
||
def load_trips(filename) | ||
trips = [] | ||
|
||
trip_data = CSV.open(filename, 'r', headers: true, | ||
header_converters: :symbol) | ||
|
||
trip_data.each do |raw_trip| | ||
passenger = find_passenger(raw_trip[:passenger_id].to_i) | ||
driver = find_driver(raw_trip[:driver_id].to_i) | ||
|
||
parsed_trip = { | ||
id: raw_trip[:id].to_i, | ||
driver: driver, | ||
passenger: passenger, | ||
start_time: raw_trip[:start_time], | ||
end_time: raw_trip[:end_time], | ||
start_time: Time.parse(raw_trip[:start_time]), | ||
end_time: Time.parse(raw_trip[:end_time]), | ||
cost: raw_trip[:cost].to_f, | ||
rating: raw_trip[:rating].to_i | ||
} | ||
|
||
trip = Trip.new(parsed_trip) | ||
passenger.add_trip(trip) | ||
driver.add_driven_trip(trip) | ||
trips << trip | ||
end | ||
|
||
|
@@ -67,6 +93,41 @@ def inspect | |
#{passengers.count} passengers>" | ||
end | ||
|
||
def request_trip(user_id) | ||
available_drivers = @drivers.select {|driver| driver.status == :AVAILABLE and driver.id != user_id } | ||
|
||
driver = available_drivers.find {|driver| driver.driven_trips.empty?} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check your warnings. It doesn't make a huge amount of difference in THIS code, but here and on line 102, you have a "shadowed variable". |
||
|
||
# first find the latest trip end time for each driver, then find the driver associated with the least recent trip end time | ||
driver ||= available_drivers.min_by {|driver| | ||
latest_trip = driver.driven_trips.max_by {|trip| trip.end_time} | ||
latest_trip.end_time} | ||
|
||
raise ArgumentError, 'No drivers available' if driver == nil | ||
|
||
passenger = find_passenger(user_id) | ||
|
||
input = { | ||
id: @trips.last.id + 1, | ||
driver: driver, | ||
passenger: passenger, | ||
start_time: Time.now, | ||
end_time: nil, | ||
cost: nil, | ||
rating: nil | ||
} | ||
|
||
new_trip = Trip.new(input) | ||
@trips << new_trip | ||
|
||
driver.make_unavailable | ||
driver.add_driven_trip(new_trip) | ||
|
||
passenger.add_trip(new_trip) | ||
|
||
return new_trip | ||
end | ||
|
||
private | ||
|
||
def check_id(id) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,5 +16,75 @@ def initialize(input) | |
def add_trip(trip) | ||
@trips << trip | ||
end | ||
|
||
def net_expenditures | ||
total = 0 | ||
@trips.each do |trip| | ||
total += trip.cost unless trip.end_time == nil | ||
end | ||
return total | ||
end | ||
|
||
def total_time_spent | ||
total_time = 0 | ||
@trips.each do |trip| | ||
total_time += trip.trip_duration unless trip.end_time == nil | ||
end | ||
return total_time | ||
end | ||
|
||
end | ||
|
||
class Driver < User | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For future's reference, at least while you're still less experienced with Ruby, I'd avoid declaring 2 classes inside the same file. Especially in Ruby, this can hide problems with your code during the testing process. |
||
attr_reader :vehicle_id, :driven_trips, :status, :trips | ||
|
||
def initialize(id: 0, name: "no name", vin: 0, phone: 0, status: :UNAVAILABLE, trips: []) | ||
raise ArgumentError.new "ID not valid" if id <= 0 | ||
raise ArgumentError.new "Invalid VIN" if vin.length != 17 | ||
raise ArgumentError.new "Invalid status" if status != :AVAILABLE && status != :UNAVAILABLE | ||
@id = id | ||
@name = name | ||
@vehicle_id = vin | ||
@phone = phone | ||
@status = status | ||
@driven_trips = [] | ||
@trips = trips | ||
end | ||
|
||
def average_rating | ||
sum = 0 | ||
in_progress = 0 | ||
|
||
@driven_trips.each do |trip| | ||
trip.end_time == nil ? in_progress += 1 : sum += trip.rating | ||
end | ||
|
||
valid_trips = @driven_trips.length - in_progress | ||
|
||
return valid_trips == 0 ? 0 : sum.to_f/valid_trips | ||
end | ||
|
||
def add_driven_trip(trip) | ||
raise ArgumentError, "Invalid trip object" unless trip.instance_of?(Trip) | ||
@driven_trips << trip | ||
end | ||
|
||
def total_revenue | ||
sum = 0 | ||
|
||
@driven_trips.each do |driven_trip| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't forget that in Ruby you have access to methods like |
||
sum += (driven_trip.cost - 1.65) * 0.8 unless driven_trip.end_time == nil | ||
end | ||
|
||
return sum.round(2) | ||
end | ||
|
||
def net_expenditures | ||
return super - self.total_revenue | ||
end | ||
|
||
def make_unavailable | ||
@status = :UNAVAILABLE | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!