-
Notifications
You must be signed in to change notification settings - Fork 46
Dionisia - Edges - Hotel #37
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
base: master
Are you sure you want to change the base?
Changes from all commits
37185c8
d647a3c
380801e
332855b
a4dc534
2f79288
d7fb0cd
ad67f98
a969eda
cbc8582
b5ff6f6
a2b9e42
030ce24
d691eec
0bf146e
a7cfbe5
f21593b
8b3b4e8
d5404ec
b6848da
eea072e
97d3845
4fd6a9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| 1. Implementation A has three classes: CartEntry, ShoppingCart, and Order. | ||
| Implementation B has the same three classes as well. | ||
|
|
||
| 2. For implementation A, CartEntry initializes the unit price and quantity for each item. ShoppingCart stores the entries of each item in an array. Order creates a new instance of a shopping cart and then calculates the total price of all the items in a cart with the sales tax. | ||
|
|
||
| For implementation B, CartEntry initializes the unit price and quantity for each item. ShoppingCart stores the entry of each item in an array and also calculates the price of each item. Order creates a new instance of a shopping cart and calculates the total price of each cart with all the items and the sales tax. | ||
|
|
||
| 3. For implementation A, the CartEntry establishes the quantity and price of each item. ShoppingCart stores each entry. These two classes are needed for the Order class which creates a new instance of a shopping cart and then goes through each entry in the cart to calculate the sum of all the items and their prices. It returns the total price. | ||
|
|
||
| For implementation B, CartEntry is responsible for establishing the unit price and and quantity of each item. Then it calculates the price of each type of item depending on the quantity ordered. ShoppingCart stores the entry of each item in a shopping cart. It also calculates the price of each entry by calling on the price method in CartEntry and then adding up the sums. Order creates a new instance of shopping cart. It calculates the subtotal by calling on the price method from ShoppingCart. Then it calculates the overall cost by multiplying the subtotal to the sales tax and adding that to the original subtotal amount. | ||
|
|
||
| 4. CartEntry stores each item's price and quantity. ShoppingCart stores all the entries. Order retrieves the information from CartEntry and ShoppingCart to return the total price of each cart. Both store the same info. However, I think implementation A does a better job of creating single responsibility for each class without relying too heavily on the Order class to calculate the total price. However, the subtotal variable in implementation B is much clearer on what is being calculated vs, implementation A where the variable sum is used. I wasn't sure why sum was being returned at first. | ||
|
|
||
| 5. Initially, it seemed logical to compute the the price in "lower level" classes like ShoppingCart and CartEntry. However that creates a tie between all the classes and if one is changed, then the others must be modified as well. In the first implementation, ShoppingCart doesn't rely on price being calculated in CartEntry and then Order doesn't rely on ShoppingCart for price to be calculated in order for the total price to be calculated. Total price does not directly manipulate the instance variables of the other classes. | ||
|
|
||
| 6. If items were bought in bulk, I think this would be done in a new method called bulk. I think because method A is more loosely coupled than B, it would be easier to implement in A. | ||
|
|
||
| 7. Implementation A. | ||
|
|
||
| 8. Implementation A. Although I think implementation B is a little easier to read because the variable subtotal in the method total_price was clearer to me. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| require 'date' | ||
| require 'securerandom' | ||
|
|
||
| class Block | ||
| attr_reader :check_in_date, :check_out_date, :id, :block_of_rooms | ||
| attr_accessor :rooms | ||
|
|
||
| BLOCKRATE = 100 | ||
|
|
||
| def initialize(check_in_date, check_out_date, block_of_rooms) | ||
| @id = SecureRandom.uuid | ||
| @check_in_date = check_in_date | ||
| @check_out_date = check_out_date | ||
| @block_of_rooms = block_of_rooms | ||
| @rooms = [] | ||
| end | ||
|
|
||
| def valid_block_of_rooms | ||
| if block_of_rooms > 5 | ||
| raise ArgumentError, 'Blocks can have up to 5 rooms.' | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ROOM_LIST = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] | ||
|
|
||
| def hotel | ||
| return "hotel" | ||
| end | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whoops! You should probably delete this file and all references to it. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Keeps track of 1 reservation | ||
| require_relative 'room' | ||
| require 'date' | ||
|
|
||
| # module Hotel | ||
| class Reservation | ||
| attr_reader :check_in_date, :check_out_date, :room_number, :nights_stayed | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| def initialize(check_in_date, check_out_date, room_number) | ||
| @check_in_date = check_in_date | ||
| @check_out_date = check_out_date | ||
| @room_number = room_number | ||
| raise StandardError, 'The end date cannot be before the start date.' if check_out_date <= check_in_date | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love that the logic to check if reservation dates are valid are in the Reservation itself. Nice decision :) |
||
| end | ||
|
|
||
| def nights_stayed | ||
| date_range = check_out_date - check_in_date | ||
| return date_range.to_i | ||
| end | ||
| end | ||
|
|
||
| class BlockReservation < Reservation | ||
| def initialize(check_in_date, check_out_date, room_number) | ||
| super | ||
| end | ||
|
|
||
| def block_rate | ||
| date_range = @check_out_date - @check_in_date | ||
| date_range.to_i | ||
| end | ||
| end | ||
| # end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| require 'pry' | ||
| require 'date' | ||
| require_relative 'room' | ||
| require_relative 'block' | ||
| require_relative 'reservation' | ||
| # Keeps track of the list of reservations | ||
| # module Hotel | ||
| class ReservationTracker | ||
| attr_reader :rooms, :check_in_date, :check_out_date, :reservations, :unreserved_rooms, :blocks | ||
|
|
||
| def initialize | ||
| @rooms = create_rooms | ||
| @reservations = [] | ||
| @unreserved_rooms = [] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this instance variable |
||
| @blocks = [] | ||
| # @existing_reservations = [] | ||
|
|
||
|
|
||
| end | ||
|
|
||
| # creates and accesses the list of all of the rooms in the hotel | ||
| def create_rooms | ||
| rooms = [] | ||
| (1..20).each do |room| | ||
| room_number = Room.new(room) | ||
| rooms << room_number | ||
| end | ||
| return rooms | ||
| end | ||
|
|
||
| # creates reservation and adds the reservation to the list of reservations | ||
| def create_reservation(check_in_date, check_out_date, room_number) | ||
| reservation = Reservation.new(check_in_date, check_out_date, room_number) | ||
| @reservations << reservation | ||
| # @reserved_rooms << room | ||
| # return reservation | ||
| end | ||
|
|
||
| def create_a_block(check_in_date, check_out_date, block_of_rooms) | ||
| # rooms_available is an arrary from rooms_not_reserved | ||
| rooms_available = rooms_not_reserved(check_in_date, | ||
| check_out_date) | ||
| block_reservation = Block.new(check_in_date, | ||
| check_out_date, | ||
| block_of_rooms) | ||
| block_reservation.rooms = rooms_available.pop(block_of_rooms) | ||
| @blocks << block_reservation | ||
|
|
||
| return block_reservation | ||
| end | ||
|
|
||
| # don't think i need this anymore | ||
| # def is_a_room_available?(date) | ||
| # @reservations.each do |reservation | | ||
| # return false if reservation.check_in_date >= date && reservation.check_out_date > date | ||
| # end | ||
| # # binding.pry | ||
| # return true | ||
| # end | ||
|
|
||
| # accesses the list of reservations for a specific date | ||
| def list_of_reservations(date) | ||
| return @reservations.find_all { |reservation| reservation.nights_stayed == date } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this code actually work? It looks fishy to me, and I can't tell because there aren't any tests! :( |
||
| end | ||
|
|
||
| # calculates the total cost for a given reservation | ||
| def cost_for_given_reservation(reservation) | ||
| total_cost = reservation.nights_stayed * Room::ROOM_RATE | ||
| return total_cost | ||
| end | ||
|
|
||
| # checks to see if a room is available and reserves the first available room for a given date range. Uses the rooms_not reserved method. | ||
| def reserve_room(check_in_date, check_out_date) | ||
| # set the rooms_not_reserved method and arguments to a local variable. | ||
| unreserved_rooms = rooms_not_reserved(check_in_date, check_out_date) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love this line! Very clear what's going on here. |
||
| if unreserved_rooms.length == 0 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The indentation here is off ;) |
||
| raise ArgumentError, 'No Available Rooms for Given Dates' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of raising an ArgumentError, it might make more sense to make your own custom error or just raise |
||
| else | ||
| # uses the create reservation method if there are available rooms | ||
| create_reservation(check_in_date, check_out_date, unreserved_rooms[0]) | ||
| # binding.pry | ||
| end | ||
| end | ||
|
|
||
| # accesses a list of rooms that are not reserved for a given date range | ||
| def rooms_not_reserved(check_in_date, check_out_date) | ||
| # if the reservations array is empty, this returns an array of available room numbers. If there are no reservations, all rooms can be reserved. | ||
| return @rooms.map { |room| room.room_number } if @reservations.empty? | ||
| unreserved_rooms = @rooms.map { |room| room.room_number } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love how dense and juicy and exciting the above two lines are! |
||
| # if @reservation.empty? is not 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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very funny assumption you're putting here: For the call |
||
| 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is cool code here! I like it. However... the a = [1,2,3]
b = [1,2]
a - b
# => returns [3], as expected
# a is still [1,2,3]
# b is still [1,2]So the subtraction doesn't do anything! |
||
| end | ||
| } | ||
| # unreserved_rooms returns an empty array if nothing is availible in the given date range or it will return an array of available room numbers in date range given. | ||
| # for use in the reserve_room method | ||
| return unreserved_rooms | ||
| end | ||
|
|
||
| end | ||
| # end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Keeps track of 1 room_ | ||
| class Room | ||
| attr_reader :room_number | ||
|
|
||
| ROOM_RATE = 200 | ||
|
|
||
| def initialize(room_number) | ||
| @room_number = room_number | ||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| require 'simplecov' | ||
| SimpleCov.start | ||
| require_relative 'spec_helper' | ||
|
|
||
| describe 'Block Class' do | ||
| it 'creates a new instance of a block' do | ||
| check_in_date = Date.new(2018, 9, 5) | ||
| check_out_date = Date.new(2018, 9, 8) | ||
| new_block = Block.new(check_in_date, check_out_date, 5) | ||
| expect(new_block).must_be_instance_of Block | ||
| end | ||
|
|
||
| it 'charges a rate of 100 for the BLOCKRATE' do | ||
| Block::BLOCKRATE.must_equal 100 | ||
| end | ||
|
|
||
| it 'block of rooms must equal 5' do | ||
| check_in_date = Date.new(2018, 9, 5) | ||
| check_out_date = Date.new(2018, 9, 8) | ||
| new_block = Block.new(check_in_date, check_out_date, 5) | ||
| expect(new_block.block_of_rooms).must_equal 5 | ||
| end | ||
| end | ||
|
|
||
| describe 'validate block of rooms' do | ||
| it 'raises an Argument Error, if there are more than 5 rooms in a block' do | ||
| check_in_date = Date.new(2018, 9, 5) | ||
| check_out_date = Date.new(2018, 9, 8) | ||
| new_block = Block.new(check_in_date, check_out_date, 6) | ||
| expect { new_block.valid_block_of_rooms }.must_raise ArgumentError | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| require_relative 'spec_helper' | ||
|
|
||
| describe 'hotel' do | ||
| it 'prints hotel' do | ||
| result = hotel() | ||
| expect(result).must_equal 'hotel' | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| require 'simplecov' | ||
| SimpleCov.start | ||
| require 'pry' | ||
| require 'time' | ||
|
|
||
| require_relative 'spec_helper' | ||
|
|
||
| describe 'Reservation' do | ||
| describe 'initialize' do | ||
| check_in_date = Date.new(2018, 9, 5) | ||
| check_out_date = Date.new(2018, 9, 8) | ||
| room_number = Room.new(15) | ||
| reservation = Reservation.new(check_in_date, check_out_date, room_number) | ||
|
|
||
| it 'takes a check in date, check out date, and room number' do | ||
|
|
||
| expect(reservation).must_respond_to :check_in_date | ||
| expect(reservation.check_in_date).must_equal check_in_date | ||
|
|
||
| expect(reservation).must_respond_to :check_out_date | ||
| expect(reservation.check_out_date).must_equal check_out_date | ||
|
|
||
| expect(reservation).must_respond_to :room_number | ||
| expect(reservation.room_number).must_equal room_number | ||
| end | ||
|
|
||
| it 'raises an ArgumentError for an invalid date range' do | ||
| expect{ (Reservation.new(check_out_date, check_in_date)) }.must_raise StandardError | ||
| end | ||
| end | ||
|
|
||
| describe 'nights stayed method' do | ||
| check_in_date = Date.new(2018, 9, 6) | ||
| check_out_date = Date.new(2018, 9, 10) | ||
| room_number = 15 | ||
| reservation = Reservation.new(check_in_date, check_out_date, room_number) | ||
|
|
||
| it 'calculates the number of nights stayed correctly' do | ||
|
|
||
| expect(reservation.nights_stayed).must_equal 4 | ||
| end | ||
| end | ||
| end | ||
|
|
||
| describe 'BlockReservation' do | ||
| it 'instantiates a block reservation' do | ||
| check_in_date = Date.new(2018, 9, 6) | ||
| check_out_date = Date.new(2018, 9, 10) | ||
| room_number = 15 | ||
| block_reservation = BlockReservation.new(check_in_date, check_out_date, room_number) | ||
| expect(block_reservation).must_be_instance_of BlockReservation | ||
| end | ||
|
|
||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your use of the
SecureRandomgem here to generate an ID is rad!