Skip to content

Instantly share code, notes, and snippets.

@benhawker
Created February 28, 2018 15:27
Show Gist options
  • Save benhawker/017add3ae3daa94df433291cbfd28d33 to your computer and use it in GitHub Desktop.
Save benhawker/017add3ae3daa94df433291cbfd28d33 to your computer and use it in GitHub Desktop.
Oyster another approach
require './lib/journey'
require './lib/journey_history'
class Oyster
MAX_BALANCE = 50
MIN_FARE = 1.7
attr_reader :balance, :customer_id, :journey_history
def initialize(balance: 0, customer_id:)
@balance = balance
@customer_id = customer_id
@journey_history = JourneyHistory.new
end
def top_up(amount)
raise "Max top of #{max_top_up} reached" if max_balance_reached?(amount)
@balance += amount
end
def tap_in(start_zone)
raise "Please Top up Oyster Card" if balance < MIN_FARE
deduct_fare(current_journey.fare(start_zone)) if @current_journey
@current_journey = Journey.new(start_zone: start_zone)
end
def tap_out(end_zone)
current_journey.end(end_zone)
deduct_fare(current_journey.fare(end_zone))
journey_history.add(current_journey)
# Sets the current journey back to nil as this is now completed.
@current_journey = nil
end
def current_journey
@current_journey || Journey.new
end
private
def max_balance_reached?(amount)
(amount + balance) > MAX_BALANCE
end
def deduct_fare(fare)
puts "Deducting £#{fare} from your balance of £#{balance}. New balance #{balance - fare}"
@balance -= fare
end
end
p o = Oyster.new(balance: 50, customer_id: 1)
# A 5 penalty fare should be charged.
p o.tap_in(1)
p "----------"
# A 2.90 fare should be charged.
p o.tap_in(1)
p o.tap_out(2)
p "----------"
# A 1.70 fare should be charged.
p o.tap_in(3)
p o.tap_out(4)
p "----------"
# A penalty fare should be raised
p o.tap_out(5)
p "----------"
-------
class JourneyHistory
attr_reader :journeys
def initialize(journeys=[])
@journeys = journeys
end
def add(journey)
journeys << journey
end
end
-------
class Journey
attr_reader :start_zone, :end_zone
ZONE_FARES = [
[2.4, 2.9, 3.3, 3.9, 4.7],
[2.9, 1.7, 1.7, 2.4, 2.8],
[3.3, 1.7, 1.7, 1.7, 2.4],
[3.9, 2.4, 1.7, 1.7, 1.7],
[4.7, 2.8, 2.4, 1.7, 1.7]
]
PENALTY_FARE = 5
def initialize(start_zone: nil)
@start_zone = start_zone
@end_zone = nil
fare = nil
end
def end(end_zone)
@end_zone = end_zone
end
def fare(end_zone)
return PENALTY_FARE if penalty_fare?
ZONE_FARES[start_zone - 1][end_zone -1]
end
private
def complete?
start_zone && end_zone && fare
end
def penalty_fare?
!start_zone || !end_zone
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment