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

Carets- Julia Meier- Hotel #43

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a94a144
created rake file and spec helper, created initial test for rooms.rb,…
julmeier Sep 5, 2017
2f7d797
Room class passes initialization tests
julmeier Sep 5, 2017
26db587
added Hotel class and modified Room class, both pass initialization t…
julmeier Sep 5, 2017
9f29417
Hotel and Room classes pass additional tests
julmeier Sep 5, 2017
7dee76c
made additional changes to the Hotel and Room classes
julmeier Sep 6, 2017
69acd00
fixed everything. redid MyHotel class to create rooms in hotel in the…
julmeier Sep 6, 2017
e9e19fb
hotel and room classes pass tests, added Reservation class which pass…
julmeier Sep 6, 2017
72eafc8
fixed Reservation class initialization test and passed 2nd test
julmeier Sep 6, 2017
5b382e5
altered tests and code to allow input of an actual date when creating…
julmeier Sep 6, 2017
6a2a97e
tested that a reservation has a check-in date
julmeier Sep 6, 2017
a2a3b62
Reservation class accepts a checkin and checkout date during initiali…
julmeier Sep 6, 2017
34b7b36
initializing a reservation now creates a cost
julmeier Sep 6, 2017
2816d6c
added store_reservation method to MyHotel class, which stores all new…
julmeier Sep 6, 2017
5ae6a02
altered hotel_spec to have a before-do at the top to initialize an in…
julmeier Sep 6, 2017
b6a86ed
passes test to return a an array of reservations on a given date
julmeier Sep 6, 2017
fea6898
error is raised if incorrect date format is applied to initialization…
julmeier Sep 6, 2017
25dee3d
rooms available method returns an array, but does not yet corretly po…
julmeier Sep 7, 2017
c6daf3c
method to find available rooms for a certain date range is still not …
julmeier Sep 7, 2017
e235d39
tried another way to make a rooms_available method in the hotel class…
julmeier Sep 7, 2017
9edb3ee
completed testing for the find_available_room method
julmeier Sep 7, 2017
e72c1cd
added additional test to find_rooms_available method
julmeier Sep 7, 2017
10533e1
one test still failing: Hotel_spec test_0007
julmeier Sep 7, 2017
c235d6c
fixed bug in hotel class. the find_rooms_available method did not acc…
julmeier Sep 7, 2017
436d51b
fixed bugs in find_available_rooms method (the logic for how to defin…
julmeier Sep 8, 2017
fe89f75
program raises a NoReservationAvailable error when there are no rooms…
julmeier Sep 8, 2017
288e71d
added additional test for store_reservation method - hotel_spec lines…
julmeier Sep 8, 2017
245ac65
added and tested a print_reservations_by_date method to hotel, and re…
julmeier Sep 8, 2017
92ea61a
created block class and associated methods in hotel class, passes ini…
julmeier Sep 8, 2017
f886d28
completed first user story- As an administrator, I can create a block…
julmeier Sep 8, 2017
fbc9594
last commit incorrectly stated I had completed the first user story..…
julmeier Sep 8, 2017
eac82f0
added a block_reserved attribute to the reservations class. removed c…
julmeier Sep 8, 2017
305b2e4
created find_unassigned_block_reservations method - passes first two …
julmeier Sep 9, 2017
54308c2
Raises a NoPartyByThatNameError if the user enters a party_name for w…
julmeier Sep 9, 2017
bf4cd7e
I had missed the constraint that a max of 5 rooms could be reserved f…
julmeier Sep 10, 2017
b1b8d9b
tests pass for assign_block_reservation method
julmeier Sep 10, 2017
41f3657
Please DO NOT review this version. Found a bug in assign_block_reser…
julmeier Sep 11, 2017
1cb8178
fixed bug on assign_block_reservation method
julmeier Sep 11, 2017
4e79788
tested AllBlockRoomsAssignedError
julmeier Sep 11, 2017
1ca1e06
added the match_block_partyname method, which can be used to lookup p…
julmeier Sep 11, 2017
702a62b
added method to Allow a user to set different rates for different rooms
julmeier Sep 11, 2017
f2aac8b
cleaning up files for review
julmeier Sep 11, 2017
379b9ff
Hotel Revisited- answered questions and made changes to hotel files p…
julmeier Oct 1, 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
Binary file added Ada-C8_hotel.pdf
Binary file not shown.
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
49 changes: 49 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- design-activity.md -->

What classes does each implementation include? Are the lists the same?
Both implementations use these classes: CartEntry, ShoppingCart, Order.

Write down a sentence to describe each class.
Implementation A:
CartEntry - stores the unit price and quantity for an item
ShoppingCart - stores an array of CartEntry objects
Order - creates a new ShoppingCart object and calculates the total cost, including tax, of the items in the ShoppingCart.

Implementation B:
CartEntry - stores the unit price and quantity for an item (same as A)
ShoppingCart - stores an array of CartEntry objects and calculates the total cost of the items, independent of sales tax.
Order - creates a new ShoppingCart object and calculates the total cost of the items in the Shopping Cart by calling the ShoppingCart.price method and applying a sales tax.

How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper.
See attached photo called "shopping_cart_diagram.JPG" (photo of doodle diagram).

What data does each class store? How (if at all) does this differ between the two implementations?
CartEntry- stores unit_price and quantity data for each CartEntry object.
ShoppingCart- stores array of entries objects.
Order- stores cart object but no data.

What methods does each class have? How (if at all) does this differ between the two implementations?
Implementation A includes initialize methods for all three classes; only the Order class has an additional method, which calculates the total price of an order. Implementation B differs in that all classes have an additional method that calculates 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 A, the logic to compute price is retained by the Order class. In Implementation B, it is delegated to the ShoppingCart class and the Order class.

Does total_price directly manipulate the instance variables of other classes?
In Implementation A, total_pice manipulates instance variables of other classes, but Implementation B does not.

If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?
Implementation B would be easier to modify because the user can do a cost comparison of the price of the item at the item level, since there is a price method in the CartEntry class. If bulk ordering is being considered, it might help to add another class that stores the bulk ordering requirements for a specific item. For example, there may be different prices for an item that is ordered in quantities of 1-25 vs. 26-100.

Which implementation better adheres to the single responsibility principle?
Implementation B.

Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?
Implementation B.


Notes on Changes I've made to Hotel:
-created new names that make more sense if the future data structure changes: i.e. "array_of_rooms" was changed to "rooms", and "array_of_reservations" was changed to "reservations." etc.
-changed MyHotel class to be called simply Hotel
-in Block class, removed :check-in-date and :check-out attr_readers as they were not being used/referenced
-moved "find_reservations_by_date" method from Hotel class to Reservations class. Per Chris' suggestion, changed method to first calculate the date outside of the loop that generates the available rooms. changed corresponding tests.
21 changes: 21 additions & 0 deletions lib/block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#block.rb

require 'awesome_print'
require 'date'
require 'pry'

module Hotel_Chain
class Block

attr_reader :party_name, :room_rate, :reservations

def initialize(party_name, check_in_date, check_out_date, room_rate, reservations)
@party_name = party_name
@check_in_date = Date.strptime(check_in_date, "%m/%d/%Y")
@check_out_date = Date.strptime(check_out_date, "%m/%d/%Y")
@room_rate = room_rate
@reservations = reservations #array of reservation objects
end

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

class WrongDateFormatError < ArgumentError
def initialize
super ("You've entered the date in the wrong format. Please use MM/DD/YY")
end
end

class ReservationNotAvailableError < ArgumentError
def initialize
super ("A reservation is not available for the date range you have entered.")
end
end

class NoPartyByThatNameError < ArgumentError
def initialize
super ("There is no block of rooms reserved under that name. Please make sure you have the exact party name.")
end
end

class AllBlockRoomsAssignedError < ArgumentError
def initialize
super ("All the reservations made for that block of room have been assigned. You may check to see if there is a room available at the standard rate.")
end
end

class ExceededRoomLimitForBlocksError < ArgumentError
def initialize
super ("There is a 5-room maximum limit for block reservations.")
end
end
181 changes: 181 additions & 0 deletions lib/hotel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#Hotel.rb
require 'awesome_print'
require 'date'
require 'pry'

module Hotel_Chain
class Hotel

attr_reader :rooms, :reservations, :blocks

def initialize(no_of_rooms = 20)
@rooms = Array.new(no_of_rooms)
no_of_rooms.times do |room|
@rooms[room] = Room.new(room+1)
@reservations = []
@blocks = [] #an array of block objects
end
end

def list_rooms
list_array = []
i = 0
@rooms.each do |object|
list_array << "#{i+1}. Room #{object.room_id} - $#{object.rate}/night"
i += 1
end
return list_array
end

def find_reservations_by_date(date)
reservations_on_date = []
@reservations.each do |reservation|
if (reservation.check_in_date...reservation.check_out_date).cover?(Date.strptime(date, "%m/%d/%Y"))
reservations_on_date << reservation
end
end
return reservations_on_date
end

def print_reservations_by_date(date)
array = []
reservations_on_date = self.find_reservations_by_date(date)
reservations_on_date.each do |reservation|
array << "Room #{reservation.room.room_id} is reserved from #{reservation.check_in_date} to #{reservation.check_out_date}"
end
return array
end

def store_reservation(check_in_date, check_out_date)
available_rooms = []
#ap "STORE_RESERVATION START: reservations: #{reservations}"
if @reservations.length == 0 #i.e. there are no reservations at all
new_reservation = Hotel_Chain::Reservation.new(check_in_date, check_out_date)
new_reservation.room = @rooms[0]
@reservations << new_reservation
return new_reservation
elsif @reservations.length > 0
available_rooms = find_rooms_available(check_in_date, check_out_date)
if available_rooms.length == 0
raise ReservationNotAvailableError
else
new_reservation = Hotel_Chain::Reservation.new(check_in_date, check_out_date)
new_reservation.room = available_rooms[0]
@reservations << new_reservation
return new_reservation
end
end
end

def find_rooms_available(check_in_date, check_out_date)
unavailable_rooms = []

Choose a reason for hiding this comment

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

This method seems overly complicated.


check_in = Date.strptime(check_in_date, "%m/%d/%Y")
check_out = Date.strptime(check_out_date, "%m/%d/%Y")

@rooms.each do |room|
@reservations.each do |reservation|
# checks for unavailable rooms
if room.room_id == reservation.room.room_id && reservation.block_reserved == true
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && reservation.check_in_date < check_in && (reservation.check_out_date < check_out && reservation.check_out_date > check_in)
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && (reservation.check_in_date < check_out && reservation.check_in_date > check_in) && reservation.check_out_date > check_out
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && (reservation.check_in_date > check_in && reservation.check_in_date < check_out) && (reservation.check_out_date < check_out && reservation.check_out_date > check_in)
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && reservation.check_in_date < check_in && reservation.check_out_date > check_out
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && reservation.check_in_date == check_in
unavailable_rooms << room
elsif room.room_id == reservation.room.room_id && (reservation.check_in_date > check_in && reservation.check_in_date < check_out) && reservation.check_out_date == check_out
unavailable_rooms << room
end
end
end
final_available_rooms = @rooms - unavailable_rooms
return final_available_rooms
end


def reserve_block(party_name, check_in, check_out, no_of_rooms, room_rate)
if no_of_rooms > 5
raise ExceededRoomLimitForBlocksError

Choose a reason for hiding this comment

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

Good use of a custom Error.

end

local_reservation_array = []
available_rooms = find_rooms_available(check_in, check_out)

if available_rooms.length < no_of_rooms
raise ArgumentError.new("There are not enough rooms available to reserve that block")
else
no_of_rooms.times do |room|
new_reservation = store_reservation(check_in, check_out)
new_reservation.room.rate = room_rate

Choose a reason for hiding this comment

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

room rate should be passed in when you create the reservation.

new_reservation.block_reserved = true
new_reservation.status = "unassigned"
@reservations << new_reservation
local_reservation_array << new_reservation
end
end

#I want the block object to have these attributes for ease of reference.
new_block = Block.new(party_name, check_in, check_out, room_rate, local_reservation_array)
@blocks << new_block
return new_block
end

def find_unassigned_block_reservations(party_name)
#if the block has the party name, then return that block
this_block = nil
@blocks.each do |block|
if block.party_name == party_name
this_block = block
end
end

if this_block == nil
raise NoPartyByThatNameError
end

unassigned_reservations = []
this_block.reservations.each do |reservation|
if reservation.status == "unassigned"
unassigned_reservations << reservation
end
end

if unassigned_reservations.empty?
raise AllBlockRoomsAssignedError
end

return unassigned_reservations
end

def assign_block_reservation(party_name)
unassigned_reservations = find_unassigned_block_reservations(party_name)
unassigned_reservations[0].status = "assigned"
return unassigned_reservations[0]
end

#this can be used to find if there is a block reservation party name in the system
def match_block_partyname(party_name)
reserved_under = []
@blocks.each do |block|
if (block.party_name.downcase).match(party_name.downcase)
reserved_under << block.party_name
ap block.party_name
end
end
return reserved_under
end

#Allow a user to set different rates for different rooms
def create_custom_rate(check_in_date, check_out_date, rate)
new_reservation = store_reservation(check_in_date, check_out_date)
new_reservation.room.rate = rate
return new_reservation
end

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

require 'awesome_print'
require 'date'

module Hotel_Chain
class Reservation

attr_accessor :check_in_date, :check_out_date, :room, :HOTEL, :cost, :status, :block_reserved

Choose a reason for hiding this comment

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

You have a lot of attr_accessor methods here, but they don't all get set values, like cost. How does that get calculated?

You should either have a method that does the calculation for the cost of the reservation or set the cost in the initialize method.


HOTEL = Hotel_Chain::Hotel.new

#A new reservation object can be initialized by providing the check_in_date and check_out_date
#Initialization converts the admin's date inputs to convert to Ruby Date objects, and stores them in instance variables.
#After a reservation is created, this program randomly assigns a room object (without checking to see if it's available).
#I may also like to have the program assign a reservation_id (this info can live in a spreadsheet)- then I will need a method to look up a reservation by reservation_id
#reservation_ID would be set as default value of 0 here and then set in the store_reservation method based on existing reservations.
def initialize(check_in_date, check_out_date, status = "assigned")
begin
@check_in_date = Date.strptime(check_in_date, "%m/%d/%Y")
@check_out_date = Date.strptime(check_out_date, "%m/%d/%Y")
@room = HOTEL.rooms.sample
@status = "assigned" #all reservations default to "assigned", unless they are reservations made in a block
@block_reserved = false #defaults to false. the reserve_block method changes this to true.
rescue ArgumentError
raise WrongDateFormatError
end
end

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

module Hotel_Chain
class Room

attr_reader :room_id
attr_accessor :rate

def initialize(room_id, rate = 200)
@room_id = room_id
@rate = rate
end

end
end
Binary file added shopping_cart_diagram.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions specs/block_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#block_spec.rb

require_relative 'spec_helper.rb'
require 'date'
require 'pry'

describe "The Block class" do

before do
@hotel = Hotel_Chain::Hotel.new
end

describe "Initializing the Block" do

it "can be initialized" do
block_A = Hotel_Chain::Block.new("Mary Smith", "9/25/17", "9/29/17", 150, [])
block_A.class.must_be_kind_of Class
end

end #end describe
end #final end
Loading