-
Notifications
You must be signed in to change notification settings - Fork 45
Carets -- Guillermina Muro #40
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
556fd2d
0f9313f
193aa14
5cc1ce8
6d0c0c0
caaad48
05df441
69b5087
948422c
a40e794
52e1f6e
95d5d61
42d2163
ee90848
6588ebb
c250f61
1fc6199
68c903e
4300179
3f24851
184841d
7d84609
321ee8b
0e51766
83169a9
2aecad4
ed04707
38c6885
0613ddd
91a740b
ed0662b
9d3dbf0
43a8ec4
0ceabc4
4fca524
5f8b8b4
09ae73c
fd094fc
b86f790
92a06f5
0d34d0d
b5861d8
66f8a1d
5cb8ab7
8bd5695
cb7ebd0
7610816
22ae01f
fac56e9
efd0873
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,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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| ###What classes does each implementation include? Are the lists the same? | ||
| Both implementations use three classes: CartEntry, ShoppingCart and Order. However, they differ in that B's classes has price methods instead of attr_accessors. | ||
| ###Write down a sentence to describe each class. | ||
| CartEntry: Is initialized with a unit price and quantity. B's can tell you the price, while A's gives you attr_accessors to the price and quantity. | ||
| ShoppingCart: Is initialized with an empty array to called entries. B's can tell you the total price of the all of the entries, while A's gives your attr_accessor to the entries. | ||
| Order: Creates an instance of a shopping cart and has a constant variable to store 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. | ||
| Orders hold a shopping cart, they can tell you the total price with sales tax included. A shopping cart holds CartEntry objects in an array. | ||
| ###What data does each class store? How (if at all) does this differ between the two implementations? | ||
| Order holds sales tax as a constant variable and an instance of a cart as an instance variable. ShoppingCart holds multiples instances of CartEntry objects as an instance variable within an array. CartEntry has a unit price and quantity as instance variables. The two implementations do not differ on this. | ||
| ###What methods does each class have? How (if at all) does this differ between the two implementations? | ||
| A's gives you attr_accessors for their object's instance variables. However, B's has a separate method for "price." This allows for the data to remain private and from being modified. | ||
| ###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? | ||
| A's computes the the total price by accessing the unit price and quantity for the objects and directly computing using those numbers. However, B's implementation has a price method that gives you the price for each objects, so it just needs to grab the cart's price to use as a subtotal before adding the sales tax. | ||
| ###Does total_price directly manipulate the instance variables of other classes? | ||
| A's method does not currently change the instance variables, but they could if they make a mistake writing a method in Order. However, it would be impossible to do so in B's. | ||
| ###If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? | ||
| B's implementation would be easiest because you could just modify the price method to adjust when the quantity is above a certain number. In A's implementation you would have to check it for each entry within the total price loop. | ||
| ###Which implementation better adheres to the single responsibility principle? | ||
| B! | ||
| ###Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? | ||
| ###Once you've responded to the prompts, git add design-activity.md and git commit! | ||
|
|
||
| ### Hotel | ||
| My hotel module is doing a lot! It creates, modifies, and finds rooms, reservations and blocks. Some of it can definitely be moved into the classes. I refactored the available_rooms and blocked_rooms method to not rely so heavily on attr_readers from the classes. Instead of manually checking the check in and check out date within the Hotel module, I updated it so the blocks and reservations can tell you if they are available or not within that date range. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| require 'csv' | ||
| require_relative 'room' | ||
| require_relative 'reservation' | ||
| require_relative 'hotel' | ||
|
|
||
| module Hotel | ||
| class Block < Reservation | ||
| attr_accessor :reservations | ||
| attr_reader :block_id, :discount_rate, :num_of_rooms, :rooms | ||
| def initialize(input_id, input_room_number, check_in_date, check_out_date, input_block_id = 0 ) | ||
| super | ||
| @block_id = input_block_id.to_i | ||
| @discount_rate = input_id.to_f | ||
| @num_of_rooms = input_room_number.to_i | ||
| raise ArgumentError.new "Blocks can contain a maximum of 5 rooms" if @num_of_rooms > 5 | ||
| @id = nil | ||
| @room_number = nil | ||
| @room = nil | ||
| @rooms = add_rooms(check_in_date, check_out_date) | ||
| @reservations = [] | ||
| end | ||
|
|
||
|
|
||
| def add_rooms(begin_date, end_date) | ||
| block_rooms = [] | ||
| available_rooms = Hotel.available_rooms(begin_date, end_date) | ||
| i = 0 | ||
| num_of_rooms.times do | ||
| block_rooms << available_rooms[i] | ||
| i+= 1 | ||
| end | ||
| return block_rooms | ||
| end | ||
|
|
||
| def add_reservations | ||
| reservations.replace(Hotel.find_reservation_by_block_id(block_id)) | ||
| end | ||
|
|
||
| def available(begin_search, end_search) | ||
| if (begin_search >= @check_in) && (begin_search < @check_out) && (end_search >= @check_in) && (end_search <= @check_out) | ||
| return false | ||
| else | ||
| return true | ||
| end | ||
| end | ||
|
|
||
| end # => end of Block | ||
| end # => end of module |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| require 'csv' | ||
| require_relative 'room' | ||
| require_relative 'reservation' | ||
|
|
||
| module Hotel | ||
|
|
||
| ROOM_NUMBERS = (1..20) | ||
|
|
||
| HOTEL_ROOMS = ROOM_NUMBERS.map {|num| Hotel::Room.new(num, 200)} | ||
|
|
||
|
|
||
| def self.all_rooms | ||
| return HOTEL_ROOMS | ||
| end | ||
|
|
||
| def self.find_room(input_id) | ||
| HOTEL_ROOMS.each do |room| | ||
| return room if room.id == input_id | ||
| end | ||
| end | ||
|
|
||
|
|
||
| def self.find_reservation(input_id) | ||
| raise ArgumentError.new "Invalid input. Please enter Reservation ID as an Integer" if !(input_id.is_a? Integer) | ||
| all_reservations = self.all_reservations | ||
| all_reservations.each do |reservation| | ||
| return reservation if reservation.id == input_id | ||
| end | ||
| raise ArgumentError.new "Reservation ID does not exist" | ||
| end | ||
|
|
||
| def self.find_reservation_by_block_id(input_id) | ||
| raise ArgumentError.new "Invalid input. Please enter Block ID as an Integer" if !(input_id.is_a? Integer) | ||
| blocked_reservations = [] | ||
| all_reservations = self.all_reservations | ||
| all_reservations.each do |reservation| | ||
| blocked_reservations << reservation if reservation.block_id == input_id | ||
| end | ||
| raise ArgumentError.new "No Reservations found under that Block ID" if blocked_reservations.length == 0 | ||
| return blocked_reservations | ||
| end | ||
|
|
||
| def self.find_block(input_id) | ||
| all_blocks = self.all_blocks | ||
| all_blocks.each do |block| | ||
| return block if block.block_id == input_id | ||
| end | ||
| end | ||
|
|
||
| def self.all_reservations | ||
| all_reservations = [] | ||
| CSV.read('support/reservations.csv').each do |row| | ||
| reservation_id = row[0] | ||
| room_num = row[1] | ||
| check_in_date = row[2].split | ||
| check_out_date = row[3].split | ||
| block_id = row[4] ? row[4] : 0 | ||
| all_reservations.push(Hotel::Reservation.new(reservation_id, room_num, check_in_date, check_out_date, block_id)) | ||
| end | ||
| return all_reservations | ||
| end | ||
|
|
||
| def self.all_blocks | ||
| all_blocks =[] | ||
| CSV.read('support/blocks.csv').each do |row| | ||
| block_rate = row[0] | ||
| num_of_rooms = row[1] | ||
| check_in_date = row[2].split | ||
| check_out_date = row[3].split | ||
| block_id = row[4] | ||
| all_blocks.push(Hotel::Block.new(block_rate, num_of_rooms, check_in_date, check_out_date, block_id)) | ||
| end | ||
| return all_blocks | ||
| end | ||
|
|
||
| def self.cost(input_reservation_id) | ||
| raise ArgumentError.new "Invalid reservation ID. Must be Integer." if !(input_reservation_id.is_a? Integer) | ||
| all_reservations = self.all_reservations | ||
| all_reservations.each do |reservation| | ||
| return (reservation.total_cost) if reservation.id == input_reservation_id | ||
| end | ||
| raise ArgumentError.new "Reservation ID does not exist" | ||
| end | ||
|
|
||
| def self.access_reservation(input_date) | ||
| search_date = Date.new(input_date[0], input_date[1], input_date[2]) | ||
| search_reservations = [] | ||
| all_reservations = self.all_reservations | ||
| all_reservations.each do |reservation| | ||
| search_reservations << reservation if search_date.between?(reservation.check_in, reservation.check_out - 1) | ||
| end | ||
| raise ArgumentError.new "No Reservations are present on that date" if search_reservations.length == 0 | ||
| return search_reservations | ||
| end | ||
|
|
||
| def self.available_rooms(begin_date, end_date) | ||
| begin_search = Date.new(begin_date[0].to_i, begin_date[1].to_i, begin_date[2].to_i) | ||
| end_search = Date.new(end_date[0].to_i, end_date[1].to_i, end_date[2].to_i) | ||
| unavailable_rooms = [] | ||
| all_reservations = self.all_reservations | ||
| all_reservations.each do |reservation| | ||
| if reservation.available(begin_search, end_search) == false | ||
| unavailable_rooms << reservation.room | ||
| end | ||
| end | ||
| # if (begin_search >= reservation.check_in) && (begin_search < reservation.check_out) && (end_search >= reservation.check_in) && (end_search <= reservation.check_out) | ||
| # unavailable_rooms<< reservation.room | ||
| # end | ||
| available_rooms = HOTEL_ROOMS - unavailable_rooms | ||
| return available_rooms | ||
| end | ||
|
|
||
| def self.blocked_rooms(begin_date, end_date) | ||
| begin_search = Date.new(begin_date[0].to_i, begin_date[1].to_i, begin_date[2].to_i) | ||
| end_search = Date.new(end_date[0].to_i, end_date[1].to_i, end_date[2].to_i) | ||
| blocked_rooms = [] | ||
| all_the_blocks = self.all_blocks | ||
| all_the_blocks.each do |block| | ||
| # if (begin_search >= block.check_in) && (begin_search < block.check_out) && (end_search >= block.check_in) && (end_search <= block.check_out) | ||
| if block.available(begin_search, end_search) == false | ||
| block.rooms.each do |room| | ||
| blocked_rooms << room | ||
| end | ||
| end | ||
| end | ||
| return blocked_rooms | ||
| end | ||
|
|
||
| def self.truly_available(begin_date, end_date) | ||
| available_rooms = self.available_rooms(begin_date, end_date) | ||
| blocked_rooms = self.blocked_rooms(begin_date, end_date) | ||
| truly_available = available_rooms - blocked_rooms | ||
| return truly_available | ||
| end | ||
|
|
||
|
|
||
| def self.reserve_room(begin_date, end_date) | ||
| # begin_reservation = Date.new(begin_date[0], begin_date[1], begin_date[2]) | ||
| # end_reservation = Date.new(end_date[0], end_date[1], end_date[2]) | ||
| available_rooms = self.available_rooms(begin_date, end_date) | ||
| raise ArgumentError.new "No rooms are available for this date range" if available_rooms.length == 0 | ||
| return Hotel::Reservation.new(10, available_rooms[0].id, begin_date, end_date) | ||
| end | ||
|
|
||
| def self.reserve_block(rate, num_of_rooms, check_in_date, check_out_date, input_block_id) | ||
| available_rooms = truly_available(check_in_date, check_out_date) | ||
| raise ArgumentError.new "Not enough rooms are available for this date range" if available_rooms.length < num_of_rooms.to_i | ||
| return Hotel::Block.new(rate, num_of_rooms, check_in_date, check_out_date, input_block_id) | ||
| end | ||
|
|
||
| def self.block_available(block_id) | ||
| block = self.find_block(block_id) | ||
| rooms = block.rooms.length | ||
| taken = self.find_reservation_by_block_id(block_id) | ||
| return rooms - taken.length | ||
| end | ||
|
|
||
| def self.reserve_block_room(block_id) | ||
| raise ArgumentError.new "Invalid input. Please enter Block ID as an Integer" if !(block_id.is_a? Integer) | ||
| block = self.find_block(block_id) | ||
| raise ArgumentError.new "Block ID is not found" if !(block.is_a? Hotel::Block) | ||
| # block.add_rooms | ||
| availability = block_available(block_id) | ||
|
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. in this method, you've already found the block object and stored it in I would refactor this so that it relies on block more, and lets block return internal information about itself |
||
| raise ArgumentError.new "No rooms available in Block #{block_id}" if availability == 0 | ||
| array_check_in = [block.check_in.year, block.check_in.month, block.check_in.day] | ||
| array_check_out =[block.check_out.year, block.check_out.month, block.check_out.day] | ||
| new_reservation = Hotel::Reservation.new(5, block.rooms[0].id, array_check_in, array_check_out, block.block_id) | ||
| # block.add_reservations # => does nothing currently, would work if I was writing new reservations to CSV...)-':' | ||
| block.reservations << (new_reservation) | ||
|
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. ideally instead of shoveling into a block's internal property |
||
| return new_reservation | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| require_relative 'hotel' | ||
| require_relative 'room' | ||
|
|
||
| module Hotel | ||
| class Reservation | ||
| # @@reservation_id_max = 0 | ||
| attr_reader :id, :room_number, :room, :check_in, :check_out, :total_cost, :block_id | ||
| def initialize(input_id, input_room_number, check_in_date, check_out_date, input_block_id = 0) | ||
| @id = input_id.to_i | ||
|
|
||
| @room_number = input_room_number.to_i | ||
|
|
||
| @room = Hotel.find_room(@room_number) | ||
|
|
||
| @check_in = Date.new(check_in_date[0].to_i, check_in_date[1].to_i, check_in_date[2].to_i) | ||
|
|
||
| @check_out = Date.new(check_out_date[0].to_i, check_out_date[1].to_i, check_out_date[2].to_i) | ||
|
|
||
| @total_cost = cost | ||
| @block_id = input_block_id.to_i | ||
| raise ArgumentError.new "Invalid date range" if @check_in >= @check_out | ||
| end | ||
|
|
||
| def available(begin_search, end_search) | ||
| if (begin_search >= @check_in) && (begin_search < @check_out) && (end_search >= @check_in) && (end_search <= @check_out) | ||
| return false | ||
| else | ||
| return true | ||
| end | ||
| end | ||
| private | ||
| def cost | ||
| length_of_stay = (@check_out - @check_in).to_i | ||
| cost_of_stay = length_of_stay * @room.cost | ||
| return cost_of_stay | ||
| end | ||
| # def generate_id | ||
| # @@reservation_id_max += 1 | ||
| # return @@reservation_id_max | ||
| # end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| require_relative 'hotel' | ||
|
|
||
| module Hotel | ||
| class Room | ||
| attr_reader :id, :cost | ||
| def initialize(input_id, cost) | ||
| @id = input_id | ||
| @cost = cost | ||
| end # => end of initialize | ||
|
|
||
| # def is_available?(begin_date, end_date) | ||
| # @availablility.each do |reservation_id, dates| | ||
| # if (begin_date >= check_in) && (begin_date <= check_out) || (end_date >= check_in) && (end_date <= check_out) | ||
|
|
||
| end # => end of class | ||
| end # => end of module |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| require_relative 'lib/hotel.rb' | ||
| require_relative 'lib/room.rb' | ||
| require_relative 'lib/reservation.rb' | ||
|
|
||
| # Wave 3 | ||
| # User Stories | ||
|
|
||
| # As an administrator, I can create a block of rooms | ||
|
|
||
| # => To create a block you need a date range, collection of rooms and a discounted room rate | ||
| Hotel::Block.new(begin_date, end_date, num_of_rooms, discount_rate) | ||
| # => The collection of rooms should only include rooms that are available for the given date range | ||
| Block.rooms.each | ||
| # => If a room is set aside in a block, it is not available for reservation by the general public, nor can it be included in another block | ||
|
|
||
|
|
||
| # As an administrator, I can check whether a given block has any rooms available | ||
| Hotel.block_available(input_id) | ||
| # As an administrator, I can reserve a room from within a block of rooms | ||
| Hotel.reserve_block_room(input_id) | ||
|
|
||
| #Constraints | ||
| # => A block can contain a maximum of 5 rooms | ||
| # => When a room is reserved from a block of room, the reservation dates will always match the date range of the block | ||
| # => All of the availablility checking logic from Wave 2 should now respect room blocks as well as an individual |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| require_relative 'lib/hotel.rb' | ||
| require_relative 'lib/room.rb' | ||
| require_relative 'lib/reservation.rb' | ||
|
|
||
| # Wave 1 | ||
| # User Stories | ||
| # => As an administrator, I can access the list of all of the rooms in the hotel | ||
| Hotel.rooms # => list of all rooms | ||
| [Room1, Room2, Room3, Room4...Room20] | ||
| # => As an administrator, I can reserve a room for a given date range | ||
| Hotel::Reservation.new(input_room, check_in_date, check_out_date] # => creates instance of a reservation | ||
| Hotel::Reservation.new(Room1, 10222017, 10242017) | ||
| <Hotel::Reservation @id = 55, @check_in = 10222017, @check_out = 10242017, @length_of_stay = 2, @total_cost = 400> | ||
| # => As an administrator, I can access the list of reservations for a specific date | ||
| Hotel.find_by_date(input_date) | ||
| Hotel::Reservation.find_by_date(10232017) #=> should return my reservation | ||
| <Hotel::Reservation @id = 55> | ||
| # => As an administrator, I can get the total cost for a given reservation | ||
| Hotel.reservation_cost(input_id) | ||
| Hotel.find_by_id(input_id).total_cost (?) | ||
| # Constraints | ||
| # => 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 checkoutday, so the guest should not be charged for that night | ||
| # => For this wave, any room can be reserved at any time, so you don't need to worry about double booking (-: | ||
| # | ||
| # Error Handling | ||
| # => Your code should raise an error when an invalid date range is provided |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| require_relative 'lib/hotel.rb' | ||
| require_relative 'lib/room.rb' | ||
| require_relative 'lib/reservation.rb' | ||
|
|
||
| # Wave 2 | ||
| # User Stories | ||
|
|
||
| # => As an administrator, I can view a list of rooms that are not reserved for a given date range | ||
| Hotel.available_rooms(begin_date, end_date) | ||
| #=> returns array [Room Object.available true for date range] | ||
| # => As an administrator, I can reserve an available room for a given date range | ||
| Hotel.reserve_room(begin_date, end_date) | ||
|
|
||
|
|
||
| # Constraints | ||
|
|
||
| # => A reservation is allowed to start on the same day that another reservation for the same room ends | ||
|
|
||
|
|
||
| # Error Handling | ||
|
|
||
| # => Your code should raise an exception when asked to reserve a room that is not available |
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.
you should reuse
self.find_reservationhere!