Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/test/tmp/
/test/version_tmp/
/tmp/

/README.md
# Used by dotenv library to load environment variables.
# .env

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ Remember that your job is only to build the classes that store information and h

### User Stories

- As an administrator, I can access the list of all of the rooms in the hotel
<!-- - As an administrator, I can access the list of all of the rooms in the hotel
- As an administrator, I can reserve a room for a given date range
- As an administrator, I can access the list of reservations for a specific date
- As an administrator, I can get the total cost for a given reservation
- As an administrator, I can get the total cost for a given reservation -->

### Constraints

- The hotel has 20 rooms, and they are numbered 1 through 20
<!-- - The hotel has 20 rooms, and they are numbered 1 through 20
- Every room is identical, and a room always costs $200/night
- The last day of a reservation is the checkout day, so the guest should not be charged for that night
- For this wave, any room can be reserved at any time, and you don't need to check whether reservations conflict with each other (this will come in wave 2!)
- For this wave, any room can be reserved at any time, and you don't need to check whether reservations conflict with each other (this will come in wave 2!) -->

### Error Handling

Expand All @@ -88,12 +88,12 @@ Remember that your job is only to build the classes that store information and h

### User Stories

- As an administrator, I can view a list of rooms that are not reserved for a given date range
- As an administrator, I can reserve an available room for a given date range
<!-- - As an administrator, I can view a list of rooms that are not reserved for a given date range -->
<!-- - As an administrator, I can reserve an available room for a given date range -->

### Constraints

- A reservation is allowed start on the same day that another reservation for the same room ends
<!-- - A reservation is allowed start on the same day that another reservation for the same room ends -->

### Error Handling

Expand Down
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
52 changes: 52 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
What classes does each implementation include? Are the lists the same?

Each implementation includes a CartEntry class, a ShoppingCart class, and an Order class. They are the same.

Write down a sentence to describe each class.

CartEntry - A cart entry that takes in a price and quantity.
ShoppingCart - Stores all the entries.
Order - Sets up the ShoppingCart to be totaled.

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

The ShoppingCart will hold multiple entries of CartEntry in an array. Once an order is ready to be placed, Order calculates the total to include sales tax.

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

CartEntry stores the unit_price and quantity.
ShoppingCart stores entries.
Order stores an instance variable called @cart based on a new instance of ShoppingCart.new

The main difference between these two implementations is that in the first example, everything is calculated inside of the Order class.
In the second example, CartEntry creates a price method to calculate an entry. ShoppingCart also creates a price method that calculates the total inside a shopping cart by looping through each entry and adding its total to sum by referencing the price method from CartEntry. Finally, Order can take what's in the ShoppingCart and utilize ShoppingCart's price method to return a total_price that includes SALES_TAX.

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

The first implementation has one method for total_price that creates a total price.
The second implementation has three price methods that are later accessed by other classes in order to calculate their prices.

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, logic to compute price is retained in Order. In Implementation B, logic for price is delegated to ShoppingCart and CartEntry.

Does total_price directly manipulate the instance variables of other classes?

In A, yes. In B, it does not. total_price is only dealing directly with the instance variable @cart, which is created in the initialization method of Order.

If we decide items are cheaper if bought in bulk, how would this change the code?

We could add a Bulk class that takes in unit prices at different quantities. This would involve changing how shopping cart is structured.

Which implementation is easier to modify?
It would be easier to implement using implementation B because we could create a new class, then alter ShoppingCart to take in those bulk items as well.

Which implementation better adheres to the single responsibility principle?
Implementation B adheres to the single responsibility principle because its responsibility has both a state and behavior. Logic isn't all in one class, it's delegated to the classes who have that behavior.

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

Based on the answers to 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 why the resulting design would be an improvement.

My Hotel class takes on a lot of roles. It has the total method, which should be in Reservation because it is directly related to those instance variables. I decided that Hotel's job would be to manage rooms, but it does a lot of date verification, so I should make that into its own class.
41 changes: 41 additions & 0 deletions lib/date_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require "date"
require_relative "room"

require "pry"

module Hotel
class DateRange
DATE = /^[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}$/
attr_reader :check_in, :check_out

def initialize(check_in, check_out)
@check_in = Date.strptime(check_in, "%m-%d-%Y") #keep this method for date
@check_out = Date.strptime(check_out, "%m-%d-%Y") #month-day-fullyear
#test dates in ascending order
if @check_out < @check_in
raise ArgumentError.new("Dates are in an invalid range/wrong order?")
end
#test regex, test dates in past
arr = []
arr << check_in
arr << check_out
arr.each do |date_entered|
if DATE.match(date_entered)
if Date.strptime(date_entered, "%m-%d-%Y") < Date.today
raise ArgumentError.new("These are dates in the past")
end
else
raise ArgumentError.new("Date does not match XX-XX-XXX format")
end
end
end

def date_range
array = []
(check_in..check_out).each do |d|
array << "#{d.month}-#{d.day}-#{d.year}"
end
return array
end
end
end
81 changes: 81 additions & 0 deletions lib/hotel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require "date"
require_relative "room"
require_relative "reservation"
require_relative "date_range"

require "pry"

module Hotel
class Hotel

attr_accessor :rooms, :reservations

def initialize
@rooms = Room.all
@reservations = []
end

def available_room
#takes rooms with no reservations
res_nums = []
@reservations.each do |res|
res_nums << res.room_number.num
end
@rooms.each do |room|
unless res_nums.include? room.num
return room #returns first instance
end
end
end

def reserve_room(check_in, check_out, available_room)
dates = DateRange.new(check_in, check_out).date_range
if available_rooms_during(check_in, check_out).include? available_room
@reservations << Reservation.new(dates, available_room)
else
raise ArgumentError.new("This room isn't available")
end
end

def reservations_by_date(date) #find reservations by date
array = []
@reservations.each do |arr|
if arr.dates.include? date
array << arr
end
end
return array
end

def available_rooms_during(check_in, check_out)
dates = DateRange.new(check_in, check_out).date_range
#available rooms during requested date range
#date_range must first be defined
#list all rooms that will be available
available_rooms = []

#takes rooms with no reservations
res_nums = []
@reservations.each do |res|
res_nums << res.room_number.num
end
@rooms.each do |room|
unless res_nums.include? room.num
available_rooms << room
end
end

#takes available rooms in date_range from @reservations
@reservations.each do |res|
nights = res.dates
nights.pop #removes check out day
if (nights & dates).empty?
available_rooms << res
end
end

return available_rooms
end

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

require "pry"

module Hotel
class Reservation
attr_accessor :dates, :room_number

def initialize(dates, room_number)
@room_number = room_number
@dates = dates
end

def total
return "$#{(dates.check_out - dates.check_in).floor * 200}.00"
end

end
end
19 changes: 19 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Hotel

class Room
attr_reader :num

def initialize(num)
@num = num
end

def self.all
rooms = []
(1..20).each do |num|
rooms << Room.new(num)
end
return rooms
end
end

end
Empty file removed specs/.keep
Empty file.
5 changes: 5 additions & 0 deletions specs/coverage/.last_run.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"result": {
"covered_percent": 100.0
}
}
7 changes: 7 additions & 0 deletions specs/coverage/.resultset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"RSpec": {
"coverage": {
},
"timestamp": 1506756705
}
}
File renamed without changes.
Loading