-
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
Naheed & Dionisia's Ride Share Edges #16
base: master
Are you sure you want to change the base?
Changes from all commits
495c712
b8718c2
3393aef
17ec25d
b088120
3d2cfac
3ea0722
1416994
c5ccfe8
ab8b9d8
0439271
f978aa3
ad732d7
1823c1d
efff9d6
9c6f5cd
2c6f4e7
318e44d
25277b2
080d205
afc89f9
9513989
bbd9fa0
92b96c0
fc3e0cd
bded3e7
abafafb
7657914
3ec0d20
04c7c54
ff02f25
a03ea70
e4f838a
bbe2c4d
09e67bf
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 |
---|---|---|
@@ -0,0 +1,82 @@ | ||
module RideShare | ||
class Driver < User | ||
attr_reader :vin | ||
attr_accessor :driven_trips, :status | ||
|
||
def initialize(input) | ||
super(input) | ||
if input[:vin].length != 17 | ||
raise ArgumentError, 'ID must be 17 characters' | ||
end | ||
|
||
# valid_staus = [:AVAILABLE, :UNAVAILABLE] | ||
# if valid_staus.include?(@status) | ||
# raise ArgumentError, 'Not a valid status' | ||
# end | ||
|
||
@vin = input[:vin] | ||
@driven_trips = input[:driven_trips].nil? ? [] : input[:driven_trips] | ||
@status = input[:status] == nil ? :AVAILABLE : input[:status] | ||
end | ||
|
||
def average_rating | ||
total_ratings = 0 | ||
@driven_trips.each do |trip| | ||
total_ratings += trip.rating | ||
end | ||
|
||
if @driven_trips.length == 0 | ||
average = 0 | ||
else | ||
average = (total_ratings.to_f) / @driven_trips.length | ||
end | ||
|
||
return average | ||
end | ||
|
||
|
||
# def average_rating | ||
# ratings = @driven_trips.find { |trip| trip.rating } #FIX ME PLEASE | ||
# # binding.pry | ||
# average = ratings.sum / @driven_trips.length | ||
# total_ratings = 0 | ||
# @trips.each do |trip| | ||
# total_ratings += trip.rating | ||
# end | ||
# | ||
# if trips.length == 0 | ||
# average = 0 | ||
# else | ||
# average = (total_ratings.to_f) / trips.length | ||
# end | ||
# return average | ||
# end | ||
|
||
def add_driven_trip(trip) | ||
if trip.class != Trip | ||
raise ArgumentError.new("Can only add trip instance to driven_trips array") | ||
end | ||
@driven_trips << trip | ||
return @driven_trips | ||
end | ||
|
||
def total_revenue | ||
revenue = 0.0 | ||
income = 0.0 | ||
@driven_trips.each do |trip| | ||
if trip.cost == nil | ||
raise ArgumentError, "Trip still in progress, no revenue" | ||
else | ||
revenue = (trip.cost - 1.65) * 0.8 | ||
income += revenue | ||
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. This code would be a little more readable if the two magic numbers ( |
||
end | ||
end | ||
return income.round(2) | ||
end | ||
|
||
def net_expenditures | ||
return super - total_revenue | ||
end | ||
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. Good use of |
||
|
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,20 @@ | ||
require 'csv' | ||
require 'time' | ||
require 'pry' | ||
|
||
require_relative 'user' | ||
require_relative 'trip' | ||
require_relative 'driver' | ||
|
||
module RideShare | ||
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 | ||
|
||
|
@@ -25,52 +29,132 @@ def load_users(filename) | |
|
||
users << User.new(input_data) | ||
end | ||
|
||
return users | ||
end | ||
|
||
def load_drivers(filename) | ||
driver_data = CSV.open(filename, 'r', headers: true, header_converters: :symbol) | ||
|
||
return driver_data.map do |each_driver| | ||
user = find_passenger(each_driver[:id].to_i) | ||
# binding.pry | ||
driver = { | ||
id: each_driver[:id].to_i, | ||
trips: user.trips, | ||
vin: each_driver[:vin], | ||
status: each_driver[:status].to_sym, | ||
name: user.name, | ||
phone: user.phone_number | ||
} | ||
|
||
Driver.new(driver) | ||
end | ||
|
||
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) | ||
|
||
parsed_trip = { | ||
id: raw_trip[:id].to_i, | ||
passenger: passenger, | ||
start_time: raw_trip[:start_time], | ||
end_time: raw_trip[:end_time], | ||
cost: raw_trip[:cost].to_f, | ||
rating: raw_trip[:rating].to_i | ||
} | ||
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) | ||
raw_trip[:start_time] = Time.parse(raw_trip[:start_time]) | ||
raw_trip[:end_time] = Time.parse(raw_trip[:end_time]) | ||
parsed_trip = { | ||
id: raw_trip[:id].to_i, | ||
passenger: passenger, | ||
start_time: raw_trip[:start_time], | ||
end_time: raw_trip[:end_time], | ||
cost: raw_trip[:cost].to_f, | ||
rating: raw_trip[:rating].to_i, | ||
driver: driver | ||
} | ||
|
||
trip = Trip.new(parsed_trip) | ||
passenger.add_trip(trip) | ||
driver.add_driven_trip(trip) | ||
trips << trip | ||
|
||
end | ||
return trips | ||
end | ||
|
||
trip = Trip.new(parsed_trip) | ||
passenger.add_trip(trip) | ||
trips << trip | ||
def find_passenger(id) | ||
check_id(id) | ||
return @passengers.find { |passenger| passenger.id == id } | ||
end | ||
|
||
return trips | ||
end | ||
def find_driver(id) | ||
check_id(id) | ||
return @drivers.find { |driver| driver.id == id } | ||
end | ||
|
||
def find_passenger(id) | ||
check_id(id) | ||
return @passengers.find { |passenger| passenger.id == id } | ||
end | ||
def inspect | ||
return "#<#{self.class.name}:0x#{self.object_id.to_s(16)} \ | ||
#{trips.count} trips, \ | ||
#{drivers.count} drivers, \ | ||
#{passengers.count} passengers>" | ||
end | ||
|
||
def inspect | ||
return "#<#{self.class.name}:0x#{self.object_id.to_s(16)} \ | ||
#{trips.count} trips, \ | ||
#{drivers.count} drivers, \ | ||
#{passengers.count} passengers>" | ||
end | ||
def check_id(id) | ||
raise ArgumentError, "ID cannot be blank or less than zero. (got #{id})" if id.nil? || id <= 0 | ||
end | ||
|
||
def request_trip(user_id) | ||
chosen_driver = assign_driver(user_id) | ||
passenger = find_passenger(user_id) | ||
|
||
private | ||
valid_trip_id = [1..1000].select | ||
@trips.each do |trip| | ||
if trip.id == valid_trip_id | ||
raise ArgumentError, "ID already exists" | ||
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. I don't think this code will do what you want. Moreover, even if you had said highest_current_id = @trips.map { |t| t.id }.max
new_trip_id = highest_current_id + 1 |
||
end | ||
end | ||
|
||
def check_id(id) | ||
raise ArgumentError, "ID cannot be blank or less than zero. (got #{id})" if id.nil? || id <= 0 | ||
trip = RideShare::Trip.new(id: valid_trip_id, driver: chosen_driver, passenger: passenger, start_time: Time.now, end_time: nil, cost: nil, rating: nil) | ||
|
||
chosen_driver.add_driven_trip(trip) | ||
passenger.add_trip(trip) | ||
@trips << 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. You don't mark the driver as unavailable! |
||
return trip | ||
end | ||
|
||
def assign_driver(passenger_id) | ||
# iterates through the drivers to select and return available drivers and drivers who are not driving themselves | ||
available_drivers = @drivers.select do |driver| | ||
if driver.status == :AVAILABLE && driver.id != passenger_id | ||
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. I like that you broke this logic out as a separate method! Good instincts. |
||
driver | ||
end | ||
end | ||
|
||
# iterates through the available_drivers to see if there is a driver that has not given any trips. | ||
chosen_driver = available_drivers.find do |driver| | ||
driver.driven_trips.empty? | ||
end | ||
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. Good use of enumerables throughout this method! |
||
|
||
# if there hasn't been a driver that hasn't given any trips, then this iterates through available drivers and selects the driver who's trip ended the longest time ago. | ||
if chosen_driver.nil? | ||
furthest_date = Time.now | ||
available_drivers.each do |driver| | ||
# This assumes that driven_trips are in chronological order | ||
end_time = driver.driven_trips.last.end_time | ||
if end_time < furthest_date | ||
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. That might be a big assumption. |
||
end_time = furthest_date # sets new end time | ||
chosen_driver = driver # assigns that driver as chosen driver | ||
end | ||
end | ||
end | ||
|
||
# if there are no available drivers | ||
if chosen_driver.nil? | ||
raise ArgumentError, "No drivers available" | ||
end | ||
|
||
# if there is an available driver, changes their status | ||
chosen_driver.status = :UNAVAILABLE | ||
return chosen_driver | ||
end | ||
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. Aha, here's where you set the status. I would probably not do this yet - what if something goes wrong in trying to create the trip? Then the driver would be unavailable but not actually have an incomplete trip. |
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
require 'pry' | ||
module RideShare | ||
class User | ||
attr_reader :id, :name, :phone_number, :trips | ||
|
@@ -16,5 +17,29 @@ def initialize(input) | |
def add_trip(trip) | ||
@trips << trip | ||
end | ||
|
||
def net_expenditures | ||
cost_array = [] | ||
@trips.each do |trip| | ||
if trip.cost == nil | ||
raise ArgumentError, "Trip is in progress, no cost" | ||
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. I don't know that raising an trips.each do |trip|
if trip.cost.nil?
next
end
# ... add to the total ...
end Or even better, you could write a helper method that returns a list of complete trips: def completed_trips
return @trips.reject { |t| t.end_time.nil? }
end
def net_expenditures
completed_trips.each do |trip|
# ... same logic as before ...
end
end |
||
end | ||
cost = trip.cost | ||
cost_array << cost | ||
end | ||
return cost_array.sum | ||
end | ||
|
||
def total_time_spent | ||
time_array = [] | ||
@trips.each do |trip| | ||
if trip.end_time == nil | ||
raise ArgumentError, "Trip is in progress, no end time" | ||
end | ||
time_per_trip = trip.end_time.to_i - trip.start_time.to_i | ||
time_array << time_per_trip | ||
end | ||
return time_array.sum | ||
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.
All these driver methods will fail for incomplete trips!