Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
da1fe49
Add coverage directory to .gitignore file
unkcodesquick Sep 4, 2018
d4e674e
created room spec tests
unkcodesquick Sep 4, 2018
9edc68c
Settled on reservations manager class
unkcodesquick Sep 4, 2018
f683f66
removed list method
unkcodesquick Sep 4, 2018
020026a
spike - built reservation manager and room classes
unkcodesquick Sep 5, 2018
16b4e35
updated spec_helper.rb
unkcodesquick Sep 6, 2018
8314ff0
final design
unkcodesquick Sep 7, 2018
6f963c6
keyword arguments
unkcodesquick Sep 7, 2018
d0a6545
removed is_available method, save for wave 2
unkcodesquick Sep 10, 2018
5f01796
passed all tests, added reserve_room method
unkcodesquick Sep 10, 2018
914e35a
added test to reservation mgr about reserving room, added instance of…
unkcodesquick Sep 10, 2018
f7791af
Added test to check room id of reservation
unkcodesquick Sep 10, 2018
9fb7b66
Added find_room method and added instance of reservation to room object
unkcodesquick Sep 10, 2018
891c3c4
added booked_reservations method and tests
unkcodesquick Sep 10, 2018
f3c744c
add find_reservatin method to reservation clas
unkcodesquick Sep 11, 2018
92f91e3
added find_reservation
unkcodesquick Sep 12, 2018
b58469a
passed all tests
unkcodesquick Sep 12, 2018
e57bce7
fixed booked reservations method
unkcodesquick Sep 12, 2018
85afc9a
added total cost method
unkcodesquick Sep 12, 2018
9a0fbe5
trying to debug is_booked, returning false for everything
unkcodesquick Sep 12, 2018
224ff5c
fixed bug in available rooms method
unkcodesquick Sep 12, 2018
8079dd0
fixed some tests for available_rooms
unkcodesquick Sep 12, 2018
7ab2ea2
added overlaps? method to make a helper for is_booked.. sandi metz i…
unkcodesquick Sep 12, 2018
70f1cc1
fixed available rooms method, need to add more tests
unkcodesquick Sep 12, 2018
16808df
added argument error for invalid dates
unkcodesquick Sep 12, 2018
dc3cc35
added block method
unkcodesquick Sep 12, 2018
a00b55d
fixing total cost method
unkcodesquick Sep 12, 2018
74a930a
fix block, currently handling multiple rooms in a re, not a block
unkcodesquick Sep 12, 2018
aa11f95
fixed total cost method
unkcodesquick Sep 12, 2018
f612f12
fixed total cost method
unkcodesquick Sep 12, 2018
e63259f
added tests for block method and class
unkcodesquick Sep 12, 2018
2f43112
added create block and introduced reserve block room
unkcodesquick Sep 12, 2018
f47bc6f
commented out reserve block, save for next refactor
unkcodesquick Sep 14, 2018
e62cca2
updated refactors.txt
unkcodesquick Sep 14, 2018
b2ec51e
updated refactors.txt
unkcodesquick Sep 17, 2018
2d4bb1d
Design-activity
unkcodesquick Sep 25, 2018
4ef099c
updated design activity/refactors
unkcodesquick Oct 1, 2018
62d4e08
updated refactor/design activity
unkcodesquick Oct 1, 2018
7cb3090
added block spec and changed reserve room method
unkcodesquick Oct 1, 2018
523842a
pseudo code in reservations method in reservation manager class
unkcodesquick Oct 1, 2018
6d54c6d
updated available rooms method, fixing reserveroom/block functionality
unkcodesquick Oct 1, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ build-iPhoneSimulator/

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
coverage
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ If you are not familiar with what a block of hotel rooms, here is a brief descri

## Before Submissions

Usually by the end of a project, we can look back on what we made with a clearer understanding of what we actually needed. In industry, this is a great time to do a refactor of some sort. For this project however, you're off the hook... for the moment. We will be revisiting our hotels later on on the course, and you may want to make some changes at that point.
Usually by the end of a project, we can look back on what we made with a clearer understanding of what we actually needed. In industry, this is a great time to do a refactor of some sort. For this project however, you're off the hook... for the moment. We will be revisiting our hotels later on on the course, and you may want to make some changes at that point.

- Create a new file in the project called `refactors.txt`
- Make a short list of the changes that you could make, particularly in terms of naming conventions
Expand All @@ -139,4 +139,27 @@ You should not be working on these (or even thinking about them) until you have
- Create a CLI to interact with your hotel system

## What we're looking for
You can find what instructors will be looking for in the [feedback](feedback.md) markdown document.
You can find what instructors will be looking for in the [feedback](feedback.md) markdown document.


Revisiting Hotel
Now that we've got you thinking about design, spend some time to revisit the code you wrote for the Hotel project. For each class in your program, ask yourself the following questions:

What is this class's responsibility?
You should be able to describe it in a single sentence.
Is this class responsible for exactly one thing?
Does this class take on any responsibility that should be delegated to "lower level" classes?
Is there code in other classes that directly manipulates this class's instance variables?
You might recall writing a file called refactor.txt. Take a look at the refactor plans that you wrote, and consider the following:

How easy is it to follow your own instructions?
Do these refactors improve the clarity of your code?
Do you still agree with your previous assesment, or could your refactor be further improved?
Activity
Based on the answers to each set of the above questions, identify one place in your Hotel project where a class takes on multiple roles, or directly modifies the attributes of another class. Describe in design-activity.md what changes you would need to make to improve this design, and how the resulting design would be an improvement.

If you need inspiration, remember that the reference implementation exists.

Then make the changes! Don't forget to take advantage of all the tests you wrote - if they're well structured, they should quickly inform you when your refactoring breaks something.

Once you're satisfied, git commit your changes and then push them to GitHub. This will automatically update your pull request.
48 changes: 48 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
1. The two implementations have the same classes but their utilization and functionality of the class are different.
2. Implementation A:
- Cart Entry: stores data for individual cart entries
- Shopping Cart: stores a collection of instances of cart entries
- Order: creates and calculates full order details
Implementation B:
- CartEntry: stores data for individual entry and calculates price
- ShoppingCart: stores collection of instances of entries and calculates sum of a cart.
- Order: calculates total order cost including Tax and stores instances of Cart
3. In Implementation A - the classes are heavily dependent upon one another. The Order class depends on the ShoppingCart class and does all of the work. Any changes done in one of the lower classes changes the Order class.

Implementation B - the classes are still dependent upon each other but are more loosely coupled because each of the classes includes a specific class method that will calculate price. A change in one of the lower classes has less of an event on the Order class.

4. Data - in both classes each class stores the same data except implementatin B also calculates out price per entry and shopping Cart in addition to just storing quantity and unit price.

5. Implementation A - The order class stores all the methods and functionality that this program would need to accomplish. It creates an instance of the cart and then calculates it's total cost.

Implentation B - Each of the classes is able to calculate the cost/price associated with its specific object. This makes the classes more independent of each other.

6. I think it makes sense to delegate price computation to lower classes and still have total computed in order. Each class is responsible for knowing the information respective to the instances and objects it creates. In implementation A, total_price manipulates instances of the other classes to produce a total. In implementation B, total_price does not directly manipulate instances of other classes but instead calls upon them to use their own methods to give it what it needs.

7. To include a discount for bulk buying, it would be much easier to implement this new feature in Impmentation B. The variable and corresponding method change could be added to the lower level classes and the class Order would be non the wiser to the change but still deliver what the program needs to accomplish.

8. Both Implementations mostly stick to the single responsibility principles except for Implementation A's Order class. Implementation A stores data about a cart and calculates its total cost but is also responsible for calculating the costs of the instances in the two other classes.

9. ImplementationB is more loosely coupled.

--

Hotel
- Reservation manager
- manages/creates relationships between rooms and reservations
- Room factory can be moved to the room class.
- There is no code in the lower classes that would directly influence instance variables in this class.

- Reservation
- holds all pertinent information to a specific instance of reservation
- refactor reservation to be more generic and usable for block rooms.

- Room
- holds all pertinent information to a specific room
- can take on the factory of rooms from ReservationManager Class

- Block
- manages information specific to a block.
- remove reservation responsibility from block class

My refactors doc was clear but a little bit scant. I think I could've been more thorough and thoughtful in creating it. But combined with the design activities and instructor feedback, I feel like I have a clear idea of what changes need to be made.
14 changes: 14 additions & 0 deletions lib/DateRange.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# module Hotel
# class DateRange
# def initialize(check_in, check_out)
# @check_in = Date.parse(check_in)
# @check_out = Date.parse(check_out)
# end
#
# def overlap
# end
#
# def include
# end
#
# def number_of_nights
31 changes: 31 additions & 0 deletions lib/block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'pry'


module Hotel
class Block

attr_reader :rooms, :reservations, :date_range, :check_in, :check_out, :discount_rate, :id

def initialize(number, check_in:, check_out:, number_of_rooms:1, discount_rate: 0.8)
@id = number
@check_in = Date.parse(check_in)
@check_out = Date.parse(check_out)
@date_range = (@check_in...@check_out)
@rooms = [] #if i change this to rooms can i use available rooms on it?
@discount_rate = discount_rate
@reservations = []
#change this to standard error / rescue
if @check_out != nil
if @check_out <= @check_in
raise ArgumentError, "Invalid date range"
end
end
end

# def available_rooms_in_block(check_in, check_out)
# available_rooms = self.rooms.select {|room| room.is_booked?(check_in, check_out) == false}
# #loop through Reservations @match dates on the reservations#reject dates that match
# return available_rooms #array
# end
end
end
6 changes: 6 additions & 0 deletions lib/refactors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Refactors for Hotel
- change reserve method so it can be used for block reseration
hve it pull rooms from a vairable- that can be plugged in i.e.
available rooms method for any kind of reservation and rooms on hold for block reservations
- figure out how to handle blocked rooms that are not reserved yet and only allow certain people to reserve, m
maybe need to supply block id?
50 changes: 50 additions & 0 deletions lib/reservations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

# require 'Date'

module Hotel
COST_OF_ROOM = 200
class Reservation
attr_reader :id, :check_in, :check_out, :rooms, :total_cost, :date_range, :discount_rate



def initialize(id_num, number_of_rooms:1, check_in:, check_out:, discount_rate: 1, block_id:'')
@id = id_num
@block_id = block_id
@check_in = Date.parse(check_in)
@check_out = Date.parse(check_out)
@date_range = (@check_in...@check_out)
@rooms = []
@discount_rate = discount_rate
#change this to standard error / rescue
if @check_out != nil
if @check_out <= @check_in
raise ArgumentError, "Invalid date range"
end
end
end

def find_reservation(date)
date = Date.parse(date)
return self.date_range.include? date
end

def overlaps?(check_in, check_out)
existing_check_in = self.check_in
existing_check_out = self.check_out
if existing_check_in <= check_out && existing_check_in >= check_in
return true
elsif check_in <= existing_check_out && existing_check_out <= check_out
return true
else
return false
end
end

def total_cost
total_cost = self.date_range.count * self.rooms.length * COST_OF_ROOM * self.discount_rate
return total_cost
end

end
end
119 changes: 119 additions & 0 deletions lib/reservations_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
require 'pry'
# require 'Date'

require_relative 'room'
require_relative 'reservations'
require_relative 'block'
#reservations manager
module Hotel
class ReservationManager

attr_reader :rooms, :reservations

def initialize(number_of_rooms)
@reservations = []
@blocks = []
@rooms = []
#move this factory over to room class
(1..number_of_rooms).each do |number|
@rooms << Room.new(number)

Choose a reason for hiding this comment

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

This should be a factory method in Room.

end
end

def find_room(id) #what is this method used for?
@rooms.each do |room|
if room.id == id
return room
end
end
end

def find_block(block_id)
@blocks.each do |block|
if block.id == id
return block
end
end
end

def booked_reservations(date)
return @reservations.select {|reservation| reservation.find_reservation(date) == true}
end

def reserve_room(check_in, check_out, number_of_rooms: 1, block_id:'')
new_reservation = Reservation.new(@reservations.length + 1, number_of_rooms: number_of_rooms, check_in: check_in, check_out: check_out, block_id:block_id)
assigned_rooms = available_rooms(check_in, check_out, block_id:block_id).last(number_of_rooms)
assigned_rooms.each do |room|
new_reservation.rooms << room.id
find_room(room.id).reservations << new_reservation
if block_id == Integer
find_block(block_id).reservation << new_reservation
end
end
@reservations << new_reservation
return new_reservation
end

def available_rooms(check_in, check_out, block_id:'')
if block_id == ''
available_rooms = self.rooms.select {|room| room.is_booked?(check_in, check_out) == false}
elsif block_id == Integer
available_rooms = find_block(block_id).rooms.select {|room| room.is_booked?(check_in, check_out) == false}
end
#loop through Reservations @match dates on the reservations#reject dates that match
return available_rooms #array
end

def create_block(check_in, check_out, number_of_rooms: , discount_rate: 0.8)
block = Block.new(@blocks.length + 1, check_in: check_in, check_out: check_out, number_of_rooms: number_of_rooms, discount_rate: discount_rate)
rooms_to_hold = available_rooms(check_in, check_out).first(number_of_rooms)
rooms_to_hold.each do |room|
block.rooms << room.id
find_room(room.id).reservations << block# - this needs to be changed
end
@blocks << block
return block
end

# def reserve_block(check_in, check_out, number_of_rooms: , block_id: @blocks.last.id)
# block_reservation = Reservation.new(@reservations.length + 1, check_in: check_in, check_out: check_out)
# #refer to blok - create find block based on id return blocked rooms
# available_rooms() check_out).last(number_of_rooms)
# assigned_rooms.each do |room|
# new_reservation.rooms << room.id
# find_room(room.id).reservations << new_reservation
# end
# @reservations << block_reservation
# return block_reservation
# end
end

#how to account for multiple rooms for a rservation within a block_reservation

# add additional room to reservation

# def reserve_block(number_of_rooms, check_in, check_out, discount_rate: 0.80)
# while available_rooms(check_in, check_out).length > number_of_rooms
# block_reservation = Reservation.new(@reservations.length + 1, check_in: check_in, check_out: check_out, discount_rate: discount_rate)
# assigned_rooms = available_rooms(check_in, check_out).first(number_of_rooms)
# assigned_rooms.each do |room|
# block_reservation.rooms << room.id
# find_room(room.id).reservations << block_reservation
# end
# end
# @reservations << block_reservation
# return block_reservation
# end



# def @reservations.all
# return @reservations
# end
#create instance of reservation
#find available room, assign room to reservation id
#ask room - do you have availability



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

module Hotel
class Room
attr_reader :id
attr_accessor :reservations

def initialize(id_num)
@id = id_num
@reservations = []
#bookings - both res/block
#define room as physical space
end

def self.make_rooms(number_of_rooms)
rooms = []
(1..number_of_rooms).each do |number|
rooms << Room.new(number)
end
return rooms
end

#create helper methods that return boolean values - in reservmgr - create loop methods that take helper method booleans and creates an array
# def self.find_room(id)
# if room.id == id
# return room
# end
# end
#
# def find_reservation(date)
# date = Date.parse(date)
# return self.date_range.include? date
# end


def is_booked?(check_in, check_out)
check_in = Date.parse(check_in)
check_out = Date.parse(check_out)
check_dates = check_in...check_out
return false if self.reservations.length == 0
self.reservations.each do |reservation|
if reservation.date_range.cover?(check_dates)
return true
elsif reservation.overlaps?(check_in, check_out)
return true
end
end
return false
end

end
end
Empty file added spec/block_spec.rb
Empty file.
Loading