Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9b0e8a5
Lib, Speck, Rake, and Spec Helper files created.
Sep 5, 2017
25b1675
Added hotel class & HotelManagement Module. Tests passing for Hotel a…
Sep 6, 2017
a5bf73e
Added tests to reservation and Hotel class. Added reservation numner …
Sep 6, 2017
3de1164
updated reservation class and tests. reservation class now has room_n…
Sep 6, 2017
c2c919d
Added more tests to Hotel Class
Sep 6, 2017
4800909
Added rate method to reservation class and tests.
Sep 7, 2017
fc4bc05
All tests passin. Updated rooms and reservation classes (got rid of w…
Sep 7, 2017
472f74d
Rate is now a constant. Updated tests accordingly.
Sep 7, 2017
1d81dc5
Wave 2 complete
Sep 8, 2017
76cbbdf
wave 2: method to list unreserved rooms for a given range complete. t…
Sep 8, 2017
9d61cab
Additional tests for rooms_not_reserved method.
Sep 8, 2017
d0f04d7
reserve_room_for_date_range method fixed and tests passing. wave 2 co…
Sep 9, 2017
6d8c2dc
Wave 3: created block and block reservation classes.
Sep 10, 2017
c679ceb
Wave 3: block class testst passing
Sep 10, 2017
68a6906
Wave 3: block reservation class set up. inheriting from reservation c…
Sep 10, 2017
a68ce8c
Wave 3: BlockReservation class tests passing
Sep 10, 2017
29bdaf2
added to block class. checkin and check out dates.
Sep 10, 2017
a7a3f33
create block method complete tests pass.
Sep 10, 2017
bf4d70d
.
Sep 11, 2017
8c7ac00
updated conditional in rooms_not_reserved method.
Sep 11, 2017
dfd1487
can reserve a room within a block. 99% coverage.
Sep 11, 2017
d9d2022
design-activity completed
Sep 28, 2017
b8bb268
Completed design-acivity and updated hotel. Updates: refactored creat…
Sep 29, 2017
2261275
removed unnecessary commented out code
Sep 29, 2017
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
70 changes: 70 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
- What classes does each implementation include? Are the lists the same?

Each implementation includes the same three classes consisting of CartEntry, ShoppingCart, and Order.

- Write down a sentence to describe each class.

CartEntry: Initializes unit_price and quantity (implementation A & B), and calculates the price of the entry to be added to the cart (implementation B).

ShoppingCart: In both implementations, an entries array is initialized, however, the only difference is that implementation B has a price method that returns the sum of each entry utilizing the price method from the CartEntry class.

Order: Each of the order classes initializes a new instance of the ShoppingCart class and returns the total price of the shopping cart after factoring in tax.

- How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper.

Each class relies on attributes of the class prior. for example, in implementation B, the ShoppingCart class entries array will consist of the instances of the car class after the price method has been executed and the Order class returns the total price based on what is returned in the ShoppingCart class.


- What data does each class store? How (if at all) does this differ between the two implementations?

Implementation A
CartEntry: Stores a unit_price and quantity instance variables.

ShoppingCart: Stores an entires array.

Order: Stores an instance of the ShoppingCart class and a method that sums the total of the entires array and adds tax.

Implementation B
CartEntry: Stores a unit_price and quantity instance variables and a price method that returns the sum of the unit_price and quantity multiplied.

ShoppingCart: Stores an entires array and has a price method that returns the sum of all the entries in the array

Order: Stores an instance of the ShoppingCart class and has a total_price method that adds tax to the sum of entries array.


- What methods does each class have? How (if at all) does this differ between the two implementations?

Implementation A (methods in each class)
CartEntry: No methods
ShoppingCart: No methods
Order: total_price

Implementation B (methods in each class)
CartEntry: price
ShoppingCart: price
Order: total_price

- Consider the Order#total_price method. In each implementation:
- Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order

In implementation B, logic to compute total_price is broken down throughout the three classes whereas in implementation A all of the logic to compute total price resides in the order class.

- Does total_price directly manipulate the instance variables of other classes?

No, the total_price method does not directly manipulate the instance variables of the other classes.


- If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?

If items are bought in bulk, it would be easier to update the code in Implementation B, specifically within the CartEntry class as it deals with a quantity instance variable. The update can be done by adding a conditional.


- Which implementation better adheres to the single responsibility principle?

Implementation B better adheres to the single reason principle.

<!-- - Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? -->

ACTIVITY

An area in my code that needed to be updated was the hotel class, specifically the create_reservation method. The method was checking for valid date ranges in addition to creating and instance of the reservation class id the dates were valid. I fixed this by moving the date validation portion to the reservation class and creating a new method that checks for date validity. This is an improvement because it allows the hotel class to focus on creating reservations (regular and block) and return bits of information having to due with reservations and designating other functions such as checking dates to lower level classes.
27 changes: 27 additions & 0 deletions lib/block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# block
require 'date'
require 'securerandom'

module HotelManagment
class Block
attr_reader :amount_of_rooms, :check_in_date, :check_out_date, :id
attr_accessor :rooms

BLOCKRATE = 100

def initialize(check_in_date, check_out_date, amount_of_rooms)
@amount_of_rooms = amount_of_rooms
@check_in_date = check_in_date
@check_out_date = check_out_date
@rooms = []
@id = SecureRandom.uuid
end

def validate
if amount_of_rooms > 5
raise ArgumentError, '5 rooms is the Maximum a block allows'
end
end

end #class end
end #module end
24 changes: 24 additions & 0 deletions lib/block_reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# block_reservation
require 'date'

module HotelManagment
class BlockReservation < Reservation

def initialize(first_name, last_name, check_in_date, check_out_date, room_number)
super
@cost = cost
end

def block_rate

Choose a reason for hiding this comment

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

Shouldn't you simply override the rate method?

Why create the same method by a different name in a subclass?

nights = @check_out_date - @check_in_date
@cost = nights.to_i * Block::BLOCKRATE
end

# private
# def validate
# if amount_of_rooms > 5
# raise ArgumentError, '5 rooms is the Maximum a block allows'
# end
# end
end #class end
end #module end
123 changes: 123 additions & 0 deletions lib/hotel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# hotel
require_relative 'room.rb'
require 'date'

module HotelManagment
class Hotel
attr_reader :rooms, :reservations, :found_reservations, :unreserved_rooms, :blocks
def initialize
@rooms = []

Choose a reason for hiding this comment

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

If you're setting @rooms to [] in initialize, why do you have an add_20_rooms method. I would suggest instead making add_20_rooms private and calling it from initialize. I would also suggest renaming it to something less specific as to the implementation (number of rooms). That way you could extend or subclass Hotel and override the method to change the number of rooms.

@reservations = []
@found_reservations = []
@unreserved_rooms = []
@blocks = []

# add_20_rooms
end

def add_20_rooms
room_number = 1
20.times do
room = HotelManagment::Room.new(room_number)
@rooms << room
room_number += 1
end
end


# creates a reservation
def create_reservation(first_name, last_name, check_in_date, check_out_date, room_number)

Choose a reason for hiding this comment

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

The Reservation class should be checking for it being created with invalid dates.

reservation = Reservation.new(first_name, last_name, check_in_date, check_out_date, room_number)

@reservations << reservation
end



def reservations_by_date(date)
@reservations.each { |reservation|

Choose a reason for hiding this comment

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

Good use of enumerables in this project.

if reservation.check_in_date <= date && reservation.check_out_date >= date
found_reservations << reservation
end
}
return @found_reservations
end


# returns an array or rooms not reserved for a given date range
def rooms_not_reserved(check_in_date, check_out_date)
# guard clause: if the reservations array is empty, return a rooms array of room numbers. If no reservations, all rooms can be reserved for a block.
return @rooms.map { |room| room.room_number } if @reservations.empty? && @blocks.empty?

unreserved_rooms = @rooms.map { |room| room.room_number }
# if !@reservation.empty?
@reservations.each { |reservation|
if (reservation.check_in_date >= check_in_date && reservation.check_in_date <= check_out_date) || (reservation.check_out_date >= check_in_date && reservation.check_out_date <= check_out_date)
unreserved_rooms.delete(reservation.room_number)
end
}
# end

@blocks.each { |block|
if (block.check_in_date >= check_in_date && block.check_in_date <= check_out_date) || (block.check_out_date >= check_in_date && block.check_out_date <= check_out_date)
unreserved_rooms - block.rooms
end
}
return unreserved_rooms
end


# reserves the first available room for a given date range. Uses the rooms_not reserved method.
def reserve_room_for_date_range(first_name, last_name, check_in_date, check_out_date)

# set the rooms_not_reserved method and arguments to a local variable.
# rooms_not_reserved returns an empty array if there is nothing avail in given date range.
# or returns array of room numbers of the avail rooms in date range given.

rooms_unreserved_for_this_date = rooms_not_reserved(check_in_date, check_out_date)

if rooms_unreserved_for_this_date.length == 0
raise ArgumentError, 'No Available Rooms for Given Dates'
else
create_reservation(first_name, last_name, check_in_date, check_out_date, rooms_unreserved_for_this_date[0])
end
end


def create_block(check_in_date, check_out_date, amount_of_rooms)
available_rooms = rooms_not_reserved(check_in_date, check_out_date)

block = HotelManagment::Block.new(check_in_date, check_out_date, amount_of_rooms)
block.rooms = available_rooms.pop(amount_of_rooms)
@blocks << block
return block
end
# end


def reserve_room_in_block(first_name, last_name, block_id)
block = @blocks.select {|block| block.id == block_id}[0]

if block.rooms.empty?
# TODO make test
raise ArgumentError, 'No rooms left in block'
else
room_number = block.rooms.pop
HotelManagment::BlockReservation.new(first_name, last_name, block.check_in_date, block.check_out_date, room_number)
end
end

# private
# def add_20_rooms
# room_number = 1
# 20.times do
# room = HotelManagment::Room.new(room_number)
# @rooms << room
# room_number += 1
# end
# end


end #class end
end #module end
31 changes: 31 additions & 0 deletions lib/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#reservation
require 'date'


module HotelManagment
class Reservation
attr_reader :first_name, :last_name, :check_in_date, :check_out_date, :room_number, :cost


def initialize(first_name, last_name, check_in_date, check_out_date, room_number)
@first_name = first_name
@last_name = last_name
@check_in_date = check_in_date
@check_out_date = check_out_date
@room_number = room_number
@cost = cost
end

def rate
nights = @check_out_date - @check_in_date
@cost = nights.to_i * Room::RATE

Choose a reason for hiding this comment

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

You set the cost to a different value in initialize. Why?

end

def validate_dates
if check_in_date < DateTime.now || check_out_date < check_in_date
raise ArgumentError, 'Invalid dates'
end
end

end #class end
end #module end
15 changes: 15 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#room
require 'awesome_print'

module HotelManagment
class Room
attr_reader :room_number

RATE = 200

Choose a reason for hiding this comment

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

Good use of a constant!


def initialize(room_number)
@room_number = room_number
end

end #class end
end #module end
9 changes: 9 additions & 0 deletions rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs = ["lib"]
t.warning = true
t.test_files = FileList['specs/*_spec.rb']
end

task default: :test
70 changes: 70 additions & 0 deletions specs/block_reservation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require_relative 'spec_helper'
require 'date'


describe "Reservaton Class" do
describe "Initialize" do

it "Should be able to instantiate a reservation" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.must_be_instance_of HotelManagment::BlockReservation
end

it "First name should be an instance of String" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.first_name.must_be_instance_of String
end

it "Last name should be an instance of String" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.last_name.must_be_instance_of String
end

it "check_in_date should be an instance of Date" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.check_in_date.must_be_instance_of Date
end

it "check_out_date should be an instance of Date" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.check_out_date.must_be_instance_of Date
end

it "reservation_number must be instance of integer" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.room_number.must_be_instance_of Integer
end

end


describe "block_rate Method" do

it "Must respond to block_rate" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.must_respond_to :block_rate
end

it "should return the total cost based on the number of nights reserved" do
date = Date.today
new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 3, 1)
new_block_reservation.block_rate.must_equal 200
end
end

# describe "validate" do
# it "should raise error if block room amount is greater than 5" do
# date = Date.today
# new_block_reservation = HotelManagment::BlockReservation.new("marisa", "morris", date + 1, date + 6, 6)
#
# proc {new_block_reservation.validate("marisa", "morris", date + 1, date + 4, 6) }.must_raise ArgumentError
# end
# end
end
Loading