From 664fb2a51fefb3676f1eb7fc013d98afd9fd0041 Mon Sep 17 00:00:00 2001 From: Emily Cowan Date: Fri, 13 Mar 2020 11:04:23 -0700 Subject: [PATCH] Moved all files over from original hotel directory to push to the correct fork --- .DS_Store | Bin 0 -> 6148 bytes README.md | 10 ++- feedback.md | 141 ++++++++++--------------------- lib/block.rb | 54 ++++++++++++ lib/reservation.rb | 34 ++++++++ lib/reservation_manager.rb | 91 ++++++++++++++++++++ lib/room.rb | 36 ++++++++ refactors.txt | 3 + test/.DS_Store | Bin 0 -> 6148 bytes test/block_test.rb | 42 +++++++++ test/reservation_manager_test.rb | 119 ++++++++++++++++++++++++++ test/reservation_test.rb | 23 +++++ test/room_test.rb | 31 +++++++ test/test_helper.rb | 9 ++ 14 files changed, 495 insertions(+), 98 deletions(-) create mode 100644 .DS_Store create mode 100644 lib/block.rb create mode 100644 lib/reservation.rb create mode 100644 lib/reservation_manager.rb create mode 100644 lib/room.rb create mode 100644 refactors.txt create mode 100644 test/.DS_Store create mode 100644 test/block_test.rb create mode 100644 test/reservation_manager_test.rb create mode 100644 test/reservation_test.rb create mode 100644 test/room_test.rb diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d171b97be72f8a4434738593cd4f379ac2955cf3 GIT binary patch literal 6148 zcmeHKO=}ZD7=EXTI-6LHAf$qa1ra?2Nle=uM2Im_3X0Mcd+;OO&2F2e+ugF+Bx;NV z!K-JjS3mG)s3(7c{tvzDJ0FRgO*~aZ%Dgc1yfgE>vpWy(&g=jHsdTIYKn4IP7KX_b zRx^x^vod9Kvgarw;d2CFz!ummuHT$us}7}rQs946fPK3Zn&3khY>0fnrt6zH#x{lz zSYH0*hTaUm*=z4g{uguCb=qM*|CP)ol7|i-p)^HP^Qrswmfx#~M%ZarjNmS7-8RCO zDg8CycgMbA-f`?+BXjbq?}dir*#QrBEE_5J)*a9CdlkRqS#3T~T?|mFQLT|#==YbG zN;&;vzBI_`{Zc8P(-(`&gMmh~XA75CHg+C8?mrnkeZ`jo1UD{j$0d$n51lDty7j%5Q8XJYFmdB+!Zuuh9kAH;7m@E0GS5fk)8IOEkRM>&COF`V4KotK1dm1} zkmGuV#);2#<&n3 zLOA2yqA8O^mW}Kf512MHd6AU*F-oa#qmeKXoCsOfB0j0o!Q-JLcIu?dyi9>;W>%fX%0T7ee z%?*9_%fMoEiDijHfjELjL@1&NCGv_vL^$^Al2?{E6ez-h@F(Lu^2tQrPzZlI_UoJu zq%2U?N&%(7qyh=i%&_yn_UHTmWRPkp1(X5@N&%9r)~gj -### Wave 2: Room Availability +### Wave Two: Room Availability #### User Stories @@ -154,7 +158,7 @@ Remember: Your job is to only build the classes that store information and handl - A reservation is allowed start on the same day that another reservation for the same room ends -### Wave 3: Hotel Blocks +### Wave Three: Hotel Blocks If you are not familiar with what a block of hotel rooms, here is a brief description: diff --git a/feedback.md b/feedback.md index 05dd3c165..e714c975d 100644 --- a/feedback.md +++ b/feedback.md @@ -1,104 +1,55 @@ # Hotel - - - - - - -## Section 1: Major Learning Goals - - - -| Criteria | yes/no, and optionally any details/lines of code to reference | -| --- | --- | -Practices SRP by having at least two separate classes with distinct responsibilities, and test files for these two classes | ✔️ -Overall, demonstrates understanding instance variables vs. local variables. (There aren't unnecessarily too many instance variables, when it should be a local variable) | ✔️ -For each test file, tests demonstrate an understanding of instantiating objects properly, and using Arrange-Act-Assert | ✔️ -Practices pseudocode and TDD, and reflected on it by filling out the reflection questions | ✔️ -Practices git with at least 15 small commits and meaningful commit messages | ✔️ - -## Section 2: Code Review and Testing Requirements - -| Criteria | yes/no, and optionally any details/lines of code to reference | -| --- | --- | -There is a class that represents a reservation, and a second class that holds/manages a collection of reservations through composition (instance variable) | ✔️ -The logic for checking if a reservation's date overlaps with another reservation's date is complex logic that is separated into method(s) (and potentially class(es)) | ✔️ -The logic for checking if a reservation's date overlaps with another reservation's date has unit tests | ✔️ -All of the given tests run and pass | ✔️ -A test coverage tool is installed and used, and shows 95% test coverage | ✔️ - -## Section 3: Feature Requirements - -| Feature Requirement: There is a method that... | yes/no | -| --- | --- | -gives back a list of rooms, and it's tested | ✔️ -creates a specific reservation for a room for a given date range, and it has nominal test cases | ✔️ -creates a specific reservation for a room for a given date range, and it tests an edge case, such as no available room, or invalid date range | ✔️ -gives back a list of reservations on a given date. Its tests include a test that makes several reservations for a given date | ✔️ -calculates the total price for a reservation | ✔️ -gives back a list of available rooms for a given date range, and it has nominal test cases | ✔️ -gives back a list of available rooms for a given date range, and it has edge test cases, such as no available room, or invalid date range | ✔️ -creates a block of rooms | ✔️ -reserves a room from a block | ✔️ +## What We're Looking For + + + +### Test Inspection + + + +Workflow | yes / yes but no test / no +--- | --- +**Wave 1** | +List rooms | +Reserve a room for a given date range | +Reserve a room (edge case) | +List reservations for a given date | +Calculate reservation price | +Invalid date range produces an error | +**Wave 2** | +View available rooms for a given date range | +Reserving a room that is not available produces an error | +**Wave 3** | +Create a block of rooms | +Check if a block has rooms | +Reserve a room from a block | + +### Code Review + +**Baseline** | Feedback +--- | --- +Used git regularly | +Answer comprehension questions | +At least 95% test coverage | +**Design** | +Each class is responsible for a single piece of the program | +Classes are loosely coupled | +**Fundamentals** | +Names variables, classes and modules appropriately | +Understanding of variable scope - local vs instance | +Can create complex logical structures utilizing variables | +Appropriately uses methods to break down tasks into smaller simpler tasks | +Appropriately uses iterators and `Enumerable` methods | +Appropriately writes and utilizes classes | +Appropriately utilizes modules as a namespace | +**Wrap Up** | +There is a refactors.txt file | +The file provides a roadmap to future changes | ## Overall Feedback -| Overall Feedback | Criteria | yes/no | -| --- | --- | --- | -| Green (Meets/Exceeds Standards) | 14+ total in all sections | -| Yellow (Approaches Standards) | 9-13 total in all sections | -| Red (Not at Standard) | 0-8 total in all sections, or assignment is breaking/doesn’t run with less than 5 minutes of debugging | - -### Additional Feedback - - - Great work overall! You've built your first project with minimal starting code. This represents an incredible milestone in your journey, and you should be proud of yourself! I am particularly impressed by the way that you... I do see some room for improvement around... - -## Code Style Bonus Awards - - - -Was the code particularly impressive in code style for any of these reasons (or more...?) - -| Quality | Yes? | -| --- | --- | -| Perfect Indentation | ✅ -| Elegant/Clever | ✅ -| Descriptive/Readable | ✅ -| Concise | ✅ -| Logical/Organized | ✅ diff --git a/lib/block.rb b/lib/block.rb new file mode 100644 index 000000000..0a96db962 --- /dev/null +++ b/lib/block.rb @@ -0,0 +1,54 @@ +require 'date' + +require_relative 'reservation' +require_relative 'room' + +module Hotel + class Block < Reservation + + attr_reader :rooms, :rate + + def initialize(rooms, stay_begin, stay_end, rate) + super(room, stay_begin, stay_end, rate) + + @rooms = rooms.to_h { |room| [room, false]} + @rate = rate + + claim_rooms + end + + def any_available? + available_rooms = @rooms.select { |room, bool| bool == false} + if available_rooms.length > 0 + return true + else + return false + end + end + + def reserve_room(first, last) + + if first != @stay_begin || last != @stay_end + raise ArgumentError.new "#{first} - #{last} is not a valid date range!" + end + + available_rooms = @rooms.reject { |room, bool| bool == true} + if available_rooms.length == 0 + raise ArgumentError.new("There are no rooms in the block available to book!") + else + @rooms[available_rooms.keys.first] = true + end + + end + + private + + def claim_rooms + @rooms.each do |room, bool| + reservation = Hotel::Reservation.new(room, @stay_begin, @stay_end, @cost) + room.reservations << reservation + end + end + + end +end \ No newline at end of file diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..06f5c5ae6 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,34 @@ +require 'date' + +require_relative 'reservation_manager' + +module Hotel + class Reservation + + attr_reader :room, :stay_begin, :stay_end, :cost + + def initialize(room, stay_begin, stay_end, cost = 200) + @room = room + @stay_begin = stay_begin + @stay_end = stay_end + @cost = (((stay_end - stay_begin).to_i / 24) - 1) * cost + + verify_date(@stay_begin, @stay_end) + end + + def overlapping?(first, last) + @stay_begin <= last && first <= @stay_end + end + + private + + def verify_date(stay_begin, stay_end) + if stay_begin - Date.today < 0 + raise ArgumentError.new("#{stay_begin} is before today. You cannot reserve a room for a past date.") + elsif stay_begin - stay_end > 0 + raise ArgumentError.new("#{stay_end} is before #{stay_end}. The end date must be after the begin date.") + end + end + + end +end \ No newline at end of file diff --git a/lib/reservation_manager.rb b/lib/reservation_manager.rb new file mode 100644 index 000000000..dcb3f6d77 --- /dev/null +++ b/lib/reservation_manager.rb @@ -0,0 +1,91 @@ +require 'date' + +require_relative 'block' + +# require_relative 'reservation' +# require_relative 'room' + +module Hotel + class ReservationManager + + attr_reader :rooms + + def initialize + @rooms = create_rooms + end + + def new_reservation(first, last) + available_rooms = @rooms.select { |room| room.available?(first, last)} + if available_rooms.length == 0 + raise ArgumentError.new "There are no available rooms to book!" + end + + reservation = Reservation.new(available_rooms[0], first, last) + available_rooms[0].reservations << reservation + end + + def new_block(rooms, block_begin, block_end, rate) + if rooms.length > 5 + raise ArgumentError.new("#{rooms.length} is more than the maximum number of allowed rooms for a block.") + end + + rooms.each do |room| + if !room.available?(block_begin, block_end) + raise ArgumentError.new("Room #{room.number} is not available for the dates #{block_begin} - #{block_end}.") + end + end + + block = Hotel::Block.new(rooms, block_begin, block_end, rate) + + end + + def reserve_block_room(block, stay_begin, stay_end) + block.reserve_room(stay_begin, stay_end) + end + + def all_reservations_by_room(num, first, last) + room = @rooms.select { |room| room.number == num} + + matching_reservations = room[0].reservations.select { |reservation| reservation.overlapping?(first, last)} + + return matching_reservations + end + + def all_reservations_by_date(first, last) + matching_reservations = [] + + @rooms.each do |room| + matches = room.reservations.select { |reservation| reservation.overlapping?(first, last)} + matches.each do |match| + matching_reservations << match + end + end + + return matching_reservations + end + + def rooms_list + list = "" + @rooms.each do |room| + list += "Room Number: #{room.number}\n" + end + return list + end + + def room_list_by_availability(first, last) + available_rooms = @rooms.select { |room| room.available?(first, last)} + + return available_rooms + end + + private + + def create_rooms + rooms = [] + 20.times do |i| + rooms << Hotel::Room.new(i + 1) + end + return rooms + end + end +end \ No newline at end of file diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..d5d5f886f --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,36 @@ +require 'date' + +require_relative 'reservation_manager' +require_relative 'reservation' + +module Hotel + class Room + + attr_reader :number, :reservations, :block_reservations, :is_block_claimed + + def initialize(number) + @number = number + @reservations = [] + end + + def available?(stay_begin, stay_end) + overlapping_reservations = self.reservations.select { |reservation| reservation.overlapping?(stay_begin, stay_end)} + + if overlapping_reservations.length > 0 + return false + else + return true + end + end + + def find_reservations(first, last) + matching_reservation = @reservations.select { |reservation| reservation.overlapping?(first, last)} + if matching_reservation.length > 0 + return matching_reservation[0] + else + return nil + end + end + + end +end \ No newline at end of file diff --git a/refactors.txt b/refactors.txt new file mode 100644 index 000000000..96ad90009 --- /dev/null +++ b/refactors.txt @@ -0,0 +1,3 @@ +Find better/more consistent naming conventions for my stay begin/stay end date objects. +More clearly defining the responsibility of the reservation manager class as well as it's relationship with the other classes. +Figuring out what weird thing is going on with my date subtraction during the calculation of stay cost. \ No newline at end of file diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0