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

Pipes - Angela- Hotel #45

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e30668e
Create all files for both folders lib and specs
awilson2017 Sep 6, 2017
5e10fe1
Write implimentation and specs for Room class. Write test for paramet…
awilson2017 Sep 6, 2017
3688ea9
Remove Room class and specs because I realized it had no functionalitiy.
awilson2017 Sep 8, 2017
ec3daeb
Reservation class: add methods reservation_id and total_cost.
awilson2017 Sep 9, 2017
bd0473f
Admin Class: Add methods list_of_rooms, add_reservation, list_reserva…
awilson2017 Sep 10, 2017
15c644b
realize previous git commits were committed for lib folder.
awilson2017 Sep 10, 2017
87cc702
Write tests for methods list_of_rooms, add_reservation, and list_rese…
awilson2017 Sep 10, 2017
c727184
Write reserve available room by date range method and tests.
awilson2017 Sep 10, 2017
07544d9
Big Picture: Refactoring Reservation class to dual as Block and Reser…
awilson2017 Sep 10, 2017
11e312e
Refactor Admin class to create method create_block_by_date.
awilson2017 Sep 11, 2017
a6a88f9
Admin Class: Add methods create_block_by_date, find_block, list_avail…
awilson2017 Sep 11, 2017
3306518
The tests for refactored Admin class were turned off during wave 3's …
awilson2017 Sep 11, 2017
e8f505b
try to refactor DateRange class to instructional staff's recommendati…
awilson2017 Oct 1, 2017
727c36e
Regarding testing: all tests from the first submission now pass. Work…
awilson2017 Oct 2, 2017
1392f27
Add test for calculating both full and discount price
awilson2017 Oct 2, 2017
37f305d
Admin Class: Refactor create_block_... method to automatically create…
awilson2017 Oct 2, 2017
9f6caa3
complete the desigh_assignemnt.
awilson2017 Oct 2, 2017
fbe5f24
Refactored classes and methods that depended on DateRange instance va…
awilson2017 Oct 3, 2017
980c899
Completely refactored code so functionality is not dependent on DateR…
awilson2017 Oct 3, 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
13 changes: 13 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'rake/testtask'

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

task default: :test


puts
44 changes: 44 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
What classes does each implementation include? Are the lists the same?
- Each implementation has the same class names:
1. CartEntry
2. ShoppingCart
3. Order
- The lists, what I interpret as list of classes, is the same.

Write down a sentence to describe each class.
1. CartEntry - Responsible for creating entries for the cart
2. ShoppingCart - responsible for making carts that can hold entries and their prices
3. Order - calculates the shopping carts' entries total price

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

What data does each class store? How (if at all) does this differ between the two implementations?
- From what I can tell, each implementation's classes store the same thing. ShoppingCart = entries and order = shopping cart instances.

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


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?
- Imp A delegated to both ShoppingCart and CartEntry by utilizing their instance variables
- Imp B did not, it was wrapped up nicely so that only messages were sent not responsibilities.

Does total_price directly manipulate the instance variables of other classes?
- Imp A yes. it manipulates CartEntry#unit_price and CartEntry#quantity
- Imp 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?
- Imp B is easier to change than Imp A. We would add the logic to CartEntry#price

Which implementation better adheres to the single responsibility principle?
- Imp B

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

____________________________________

My Hotel

Hotel::Admin#add_reservation_to_block method was tightly coupled to Block class per Dan's comment. So I refactored the code so only messages were sent between the two classes and those loosely coupled them. For example, I added the instance reservation directly to Block#reservation_array and this was a poor idea.
122 changes: 122 additions & 0 deletions lib/Admin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
require_relative 'reservation'
require_relative 'block'
require 'pry'
require 'date'

module Hotel
class Admin

attr_reader :blocks, :room_nums, :reservations_array

def initialize
@blocks = []
@room_nums = []
20.times do |i|
@room_nums << (i + 1)
end

Choose a reason for hiding this comment

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

I like that rooms are just integers here. Makes the design much simpler.


# @reservations_array1 = []

end # end initialize



def list_of_rooms
return Array.new(room_nums)
end


# I do not remember why I had this method. Kept it for future reference.
# def add_block(room_num_array, check_in, check_out, block_id, discount_percent: 0)
# @blocks << Hotel::Block.new(room_num_array, check_in, check_out, block_id, discount_percent: 0)
# end

# Wave 2 requirement. Add reservation only no block
# Kept this code because wave 2 requires it. As for instructor feedback provided after first submition. Please see the create_block_by_date method on line 87'ish
def add_reservation(room_selection, check_in, check_out)
# self.add_block()
# self.add_reservation_to_block()
@reservations << Hotel::Reservation.new(room_selection, check_in, check_out)
end


def list_reservations(date)
rez_by_date = []
@blocks.each do |block|
if block.block_date_range.include(date)
block.reservations_array.each do |reservation|
rez_by_date << reservation
end
end
end
return rez_by_date
end

def list_vacancies(check_in, check_out)
available_rooms = list_of_rooms

date_range = DateRange.new(check_in, check_out)


@blocks.each do |block|
if block.block_date_range.overlap?(date_range)
block.room_num_array.each do |room_num|
available_rooms.delete(room_num)
end
end
end

return available_rooms
end

# creates block with available room for a given date range. Dan, I read you original feedback about the discount_percent passing through to calc price and ran out of time for testing. Now I worked on it for a while and I was not able to solve it. I will ask Charles for help.
def create_block_by_date(rooms_per_block, check_in, check_out, block_id, discount_percent: 0.0)
while self.list_vacancies(check_in, check_out).empty?
raise StandardError("No more vacancies!")
end

room_num_array = self.list_vacancies(check_in, check_out).take(rooms_per_block).to_a

# take one of the rooms from the room_num_array to make a reservation
room_num = room_num_array.first

new_block = Hotel::Block.new(room_num_array, check_in, check_out, block_id, discount_percent: 0.0)

new_block.make_reservation(room_num, check_in, check_out, discount_percent: 0)

@blocks << new_block
end

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


# Dan I saw your original feedback about the below method not being necessary. My thought at the time was single responsibility for this method and then utiling it in the find_rooms_from_block method. If my thinking is incorrect, please let me know.
def list_available_blocked_rooms(id)
#find the block.
# access its assigned rooms
return self.find_block(id).room_num_array
end


def find_rooms_from_block(id, num_rooms_to_reserve)
return self.list_available_blocked_rooms(id).take(num_rooms_to_reserve)
end


def add_reservation_to_block(id, num_rooms_to_reserve, check_in, check_out, discount_percent: 0)
block = self.find_block(id)
num_rooms_to_reserve = self.find_rooms_from_block(id, num_rooms_to_reserve)

num_rooms_to_reserve.length.times do |room_num|
# block.reservations_array << Hotel::Reservation.new(room_num, check_in, check_out, discount_percent: 0)
block.make_reservation(room_num, check_in, check_out, discount_percent: 0)
end
end
end # end class
end # end module
40 changes: 40 additions & 0 deletions lib/Block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'date'

require_relative 'daterange'

module Hotel
class Block
COST_PER_NIGHT = 200.00

attr_reader :room_num_array, :block_date_range, :discount_percent, :block_id, :reservations_array

def initialize(room_num_array, check_in, check_out, block_id, discount_percent: 0)


@room_num_array = room_num_array
@block_date_range = DateRange.new(check_in, check_out)
# what to automate block_id and was stumped on implementation. So I opted for manuel entry
@block_id = block_id
@discount_percent = discount_percent


@reservations_array = []
end



def total_cost
full_price = (@block_date_range.total_num_of_nights) * COST_PER_NIGHT
discount = full_price * (discount_percent/100.0)
return total_cost = full_price - discount
end


def make_reservation(room_num, check_in, check_out, discount_percent: 0)
reservations_array << Hotel::Reservation.new(room_num, check_in, check_out, discount_percent: 0)
end



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


module Hotel

class DateRange

attr_reader :check_in, :check_out

def initialize(check_in, check_out)
raise ArgumentError.new("Please enter a Check Out date that comes after Check In date.") if check_in >= check_out

@check_in = check_in
@check_out = check_out
end


def include(date)
if date >= @check_in && date <= @check_out
return true
end
end

def overlap?(other)
return !(other.check_out <= @check_in || other.check_in >= @check_out)
end

def total_num_of_nights
return check_out - check_in
end




end
end
34 changes: 34 additions & 0 deletions lib/Reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'date'

require_relative 'daterange'

module Hotel
class Reservation
COST_PER_NIGHT = 200.00

attr_reader :total_cost, :room_num, :date_range

def initialize(room_num, check_in, check_out, discount_percent: 0)

# @reservation_array = []
@total_cost = 0
@room_num = room_num
@date_range = DateRange.new(check_in, check_out)
end

# def total_cost
# full_price = (@block_date_range_array.length - 1) * COST_PER_NIGHT
# discount = full_price * (discount_percent/100.0)
# return total_cost = full_price - discount
# end

def total_cost
full_price = (@date_range.total_num_of_nights) * COST_PER_NIGHT
discount = full_price * (discount_percent/100.0)
return total_cost = full_price - discount
end



end # end class
end #end module
Loading