Skip to content
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

Sigrid & Barbara, Edges, oo-ride-share #7

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e9c2e0d
Modify TripDispatcher#load_trips to store time as Time instances. Add…
sdbenezra Aug 27, 2018
114fd9f
Correct data in trip_test.csv
sdbenezra Aug 27, 2018
0700e0a
Corrected csv data from Slack
BarbaraWidjono Aug 27, 2018
1a70fb3
Merge branch 'master' of https://github.com/BarbaraWidjono/oo-ride-share
BarbaraWidjono Aug 27, 2018
19523c5
Added .duration method
BarbaraWidjono Aug 27, 2018
8ebdc03
Added test: Calc duration of trip
BarbaraWidjono Aug 27, 2018
f9c8df4
Start work on total expenditures
sdbenezra Aug 27, 2018
50e6f8b
Complete net_expenditures method in user.rb file
sdbenezra Aug 28, 2018
6f47520
Complete test for net_expenditures method in specs/user_spec.rb file
sdbenezra Aug 28, 2018
48090a3
Removed comments
BarbaraWidjono Aug 28, 2018
ee2b789
Fix merge conflict
BarbaraWidjono Aug 28, 2018
251e6d9
Added total_time_spent method and test
BarbaraWidjono Aug 28, 2018
69519d0
Added class Driver
BarbaraWidjono Aug 28, 2018
8c0c924
Working on driver class & specs.
sdbenezra Aug 28, 2018
1928564
TripDispatcher class loads drivers without name and phone number.
sdbenezra Aug 29, 2018
aad1567
TripDispatcher now loads drivers and creates driver object array incl…
sdbenezra Aug 29, 2018
e4a9ad6
Replace user with driver in passenger array in load_driver method of …
sdbenezra Aug 29, 2018
bdb8835
Added add_driven_trip method to driver class.
sdbenezra Aug 29, 2018
cc62f35
Adding average_rating method to class Driver
BarbaraWidjono Aug 29, 2018
fb16ed7
Added total_revenue method to driver class.
sdbenezra Aug 29, 2018
1ca4aac
Added Driver.net_expenditures method
BarbaraWidjono Aug 29, 2018
629ee67
Finalize driver add driven trip and refactoring.
sdbenezra Aug 30, 2018
40ff18a
Add request_trip method in trip_dispatcher class and request_trip tes…
sdbenezra Aug 31, 2018
85fc892
Update trip.rb to correctly handle @cost value of nil. Change duratio…
sdbenezra Aug 31, 2018
9f90936
Change calculation of net_expenditures and total_time_spent in user c…
sdbenezra Aug 31, 2018
84b06e7
Change calculation of average rating and total revenue in driver clas…
sdbenezra Aug 31, 2018
2f5780a
Refactor to remove unused variables.
sdbenezra Aug 31, 2018
3f388c6
Added argument_error if an invalid user is requesting a ride
BarbaraWidjono Aug 31, 2018
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
99 changes: 99 additions & 0 deletions lib/driver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
require_relative 'user'
require 'pry'

module RideShare
class Driver < User
attr_reader :vin, :driven_trips, :status

def initialize(input)
super

@vin = input[:vin]
if @vin.length != 17
raise ArgumentError.new("Invalid VIN")
else
@vin = input[:vin]
end

@driven_trips = input[:driven_trips].nil? ? [] : input[:driven_trips]

if input[:status] != :AVAILABLE && input[:status] != :UNAVAILABLE
@status = :UNAVAILABLE
else
@status = input[:status]
end
end

def add_driven_trip(trip)
if trip.is_a? Trip
# binding.pry
@driven_trips << trip
# binding.pry
else
raise ArgumentError.new("Invalid trip instance")
end
end

def average_rating
total_num_rides = @driven_trips.length
total_sum = 0

if total_num_rides == 0
return 0
end

@driven_trips.each do |x|
# binding.pry
if x.rating == "In Progress"
next

Choose a reason for hiding this comment

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

You tended to use .each iteration to calculate totals/sum things in Driver and User, even though things like .sum is available. Honestly, I don't believe that you ALWAYS need to use fancy Enumerable methods like .sum over .each iteration every time, but I want to make sure you know that those are possibilities.

else
total_sum += x.rating
end
end

avg_rating = total_sum.to_f / total_num_rides
return avg_rating

end


def total_revenue
total_cost_all_trips = 0
total_num_rides = 0

# if total_num_rides == 0
# return 0
# end

@driven_trips.each do |x|
if x.cost == "In Progress"
next
else
total_cost_all_trips += x.cost
total_num_rides += 1
end
end

all_fees = total_num_rides * 1.65
driver_revenue = (total_cost_all_trips - all_fees) * 0.8
driver_revenue_rounded = driver_revenue.round(2)

return driver_revenue_rounded
end

def net_expenditures
net_expenditures = super
difference = net_expenditures - total_revenue
# difference = super - total_revenue # can use super in place of above code.

Choose a reason for hiding this comment

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

Good use of super here.

return difference
end

def change_availability
if @status == :AVAILABLE
@status = :UNAVAILABLE
else
@status = :AVAILABLE
end
end
end
end
22 changes: 20 additions & 2 deletions lib/trip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module RideShare
class Trip
attr_reader :id, :passenger, :start_time, :end_time, :cost, :rating
attr_reader :id, :passenger, :start_time, :end_time, :cost, :rating, :driver

def initialize(input)
@id = input[:id]
Expand All @@ -11,16 +11,34 @@ def initialize(input)
@end_time = input[:end_time]
@cost = input[:cost]
@rating = input[:rating]
@driver = input[:driver]

if @rating > 5 || @rating < 1
if @rating == nil
@rating = "In Progress"
@cost = "In Progress"
elsif @rating > 5 || @rating < 1
raise ArgumentError.new("Invalid rating #{@rating}")
end

if @end_time == nil
@end_time = "In Progress"
elsif @end_time < @start_time
raise ArgumentError, "End time is before start time"

Choose a reason for hiding this comment

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

I would much rather have nil than a string to indicate a trip is in progress.

end
end

def inspect
"#<#{self.class.name}:0x#{self.object_id.to_s(16)} " +
"ID=#{id.inspect} " +
"PassengerID=#{passenger&.id.inspect}>"
end

def duration
if @end_time == "In Progress"
return "In Progress"
else
return @end_time - @start_time
end
end
end
end
107 changes: 99 additions & 8 deletions lib/trip_dispatcher.rb
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

Expand All @@ -22,13 +26,30 @@ def load_users(filename)
input_data[:id] = line[0].to_i
input_data[:name] = line[1]
input_data[:phone] = line[2]

users << User.new(input_data)
end

return users
end

def load_drivers(filename)
drivers = []

CSV.read(filename, headers: true).each do |line|
passenger = find_passenger(line[0].to_i)
input_data = {}
input_data[:id] = line[0].to_i
input_data[:vin] = line[1]
input_data[:status] = line[2].to_sym
input_data[:name] = passenger.name
input_data[:phone] = passenger.phone_number
driver = Driver.new(input_data)
passenger_index = @passengers.find_index(passenger)
@passengers[passenger_index] = driver
drivers << driver
end
return drivers
end


def load_trips(filename)
trips = []
Expand All @@ -37,21 +58,31 @@ def load_trips(filename)

trip_data.each do |raw_trip|
passenger = find_passenger(raw_trip[:passenger_id].to_i)
driver = find_driver(raw_trip[:driver_id].to_i)
passenger_as_driver = find_driver(raw_trip[:passenger_id].to_i)


start_time = Time.parse(raw_trip[:start_time])
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],
start_time: start_time,
end_time: end_time,
cost: raw_trip[:cost].to_f,
rating: raw_trip[:rating].to_i
rating: raw_trip[:rating].to_i,
driver: driver
}

trip = Trip.new(parsed_trip)
passenger.add_trip(trip)
driver.add_driven_trip(trip)
if passenger_as_driver != nil
passenger_as_driver.add_trip(trip)
end
trips << trip
end

return trips
end

Expand All @@ -60,17 +91,77 @@ def find_passenger(id)
return @passengers.find { |passenger| passenger.id == id }
end

def find_driver(id)
check_id(id)
return @drivers.find { |driver| driver.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

private
# private

def check_id(id)
raise ArgumentError, "ID cannot be blank or less than zero. (got #{id})" if id.nil? || id <= 0
end



# Note: The user_id must correspond to a User instance
def request_trip(user_id)
# Finding the User instance
current_passenger = @passengers.find { |passenger| passenger.id == user_id }

if current_passenger == nil
raise ArgumentError.new("There is no user instance with the id #{user_id}")
end


# Checking for available drivers that do not have the same id as the user requesting a ride
available_drivers = []
@drivers.each do |x|
if x.status == :AVAILABLE && x.id != user_id.to_i

Choose a reason for hiding this comment

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

This would be a great piece of logic to move to a helper method.

available_drivers << x
end
end

# If there are available drivers, then create trip instance.
if available_drivers.length > 0
# number_of_drivers = available_drivers.length
# random_driver = available_drivers[rand(0...number_of_drivers)]
# random_driver_id = random_driver.id
first_available_driver = available_drivers.first

trip_info = {
id: @trips.length + 1,
passenger: current_passenger,
start_time: Time.now,
end_time: nil,
cost: nil,
rating: nil,
driver: first_available_driver
}

trip = Trip.new(trip_info)
@trips << trip

# Changing driver data
first_available_driver.add_driven_trip(trip)
first_available_driver.change_availability

# Changing current passenger data
current_passenger.add_trip(trip)

return trip

else
return "No available drivers"
# return nil

Choose a reason for hiding this comment

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

You should either return nil or raise an exception here, not return a string. There are a number of reasons for this, but ultimately what it comes down to is, in order to check that a string contains an error message, you need to read it.

end
end
end
end
25 changes: 25 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,30 @@ def initialize(input)
def add_trip(trip)
@trips << trip
end


def net_expenditures
trip_cost_sum = 0
@trips.each do |trip|
if trip.cost == "In Progress"
next
else
trip_cost_sum += trip.cost
end
end
return trip_cost_sum
end

def total_time_spent
total_time_as_a_passenger = 0
@trips.each do |trip|
if trip.duration == "In Progress"
next
else
total_time_as_a_passenger += trip.duration
end
end
return total_time_as_a_passenger
end
end
end
Loading