-
Notifications
You must be signed in to change notification settings - Fork 46
Amber Lynn | Edges | Hotel Assignment #38
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
cf8adaa
126b9bd
7100dcd
3a5bba7
f345ac9
261d7c6
45f6dd8
4e65aa7
f93a799
17b929b
db1d822
c5cb16e
9361831
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,28 @@ | ||
| What classes does each implementation include? Are the lists the same? | ||
| Write down a sentence to describe each class. | ||
|
|
||
| The first implementation has a CartEntry class, a ShoppingCart class and an Order class with a total_price method. The second implementation has a price method in the CartEntry class that returns a sum based on unit price and quantity; a price method in the ShoppingCart class that collects the price for each entry and stores in variable named sum which will hold the price totals of all entries; there is a total price method in the Order class that takes the price of a ShoppingCart instance and stores into a variable called subtotal. This subtotal is added by itself and multiplied by a SALES_TAX to return a total for all items in cart. | ||
| ---------- | ||
| How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. | ||
|
|
||
| In the first implementation - To create an order instance, a ShoppingCart instance must also be created. They are tied together. This creates a coupling affect. The second implementation allows each class to calculate a sum. With the first class - the price of each item can be calculated based on its quantity. A shopping cart instance does not need to be created just to get the sum. There is also a price method that returns the sum of (the sum of all items). If one were to just want to see that price for an item based on its quantity, that is done entirely separate from the ShoppingCart class. Lastly there is a total price that DOES require information from another classes method to function. However a total price cannot be assessed without having a shopping cart thus this makes sense. | ||
| ----- | ||
| What data does each class store? How (if at all) does this differ between the two implementations? | ||
| The second implementation's classes each have a method that calculates a sum. The first implementation - The order class stores dat of a shopping cart instance and calculates the price using the data from the CartEntry class. | ||
| ----- | ||
| What methods does each class have? How (if at all) does this differ between the two implementations? | ||
| The first implementation has an instantiation and a total_price while while the second has a price method for each class except the Order class holds the totl price method. The second method removes dependencies on other classes. | ||
| ----- | ||
| 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? | ||
| Does total_price directly manipulate the instance variables of other classes? | ||
| The first implementation delegates the computation through its dependency on lower level classes like ShoppingCart and CartEntry while the second implementation retains that computation within Order. | ||
| ---- | ||
| If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? The second implementation seems better because you can assign prices per item based on quantity before placing it in a cart. | ||
| ---- | ||
| Which implementation better adheres to the single responsibility principle? | ||
| implementation 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! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| def hotel | ||
| return "this is a hotel" | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| RESERVATION_MNGER | ||
|
|
||
| def list_rooms | ||
| returns array of all room instances | ||
| end | ||
|
|
||
| def find_rooms(room_number) | ||
| returns room instance that matches room_number | ||
| ? call find_room instead? | ||
| end | ||
|
|
||
| def find_available_room(specific_date) | ||
| returns an instance of room that is available for a specific date | ||
| how do i know it's available? | ||
| ask all of the reservations "is this room under any reservations for some specific date?" | ||
| end | ||
|
|
||
| def reserve_room(room_number, start_date, end_date) | ||
| - takes room instance that matches room number | ||
| - make one new reservation for one room, for given start_date and end_date | ||
| - give the new reservation instance the room instance from step one | ||
| ? - changes availability for a period of time | ||
| end | ||
|
|
||
| def list_reservations | ||
| - returns array of all reservation instances | ||
| end | ||
|
|
||
| def find_reservation(reservation_id) | ||
| - returns reservation instance that matches reservation id | ||
| ? call find_reservation | ||
| end | ||
|
|
||
| def get_total(reservation_id) | ||
| - calculates each room and number of nights reserved | ||
| - returns total | ||
| end | ||
|
|
||
|
|
||
| ROOM | ||
|
|
||
| def current_status | ||
| - returns available or unavailable | ||
| end | ||
|
|
||
| def availability | ||
| - returns date range of when room is available | ||
| end | ||
|
|
||
| def cost(number_of_nights) | ||
| - returns cost * number of nights reserved | ||
| end | ||
|
|
||
| RESERVATION | ||
|
|
||
| def room_reserved | ||
| - what is the room associated with this reservation | ||
| - return room instance is associated with this reservation | ||
| end | ||
|
|
||
| def reservation_date | ||
| - returns date reservation begins and ends | ||
| - example: 02/02/2018 - 02/04/2018 | ||
| - example: 2 days | ||
| ? tricky/fuzzy/needs to be investigated: what data type is this going to be? | ||
| end | ||
|
|
||
| def total_room_cost | ||
| - calculates rooms_reserved * cost | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| require 'time' | ||
| require 'date' | ||
|
|
||
| module Hotel | ||
| class Reservation | ||
| attr_accessor :room, :check_in, :check_out | ||
|
|
||
| def initialize(input) | ||
| @room = input[:room] | ||
| @check_in = Date.strptime(input[:check_in], '%m/%d/%Y') | ||
| @check_out = Date.strptime(input[:check_out], '%m/%d/%Y') | ||
| end | ||
|
|
||
| def room_reserved | ||
| return @room | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| require 'time' | ||
| require 'date' | ||
| require 'pry' | ||
|
|
||
|
|
||
| require_relative 'reservation' | ||
|
|
||
| module Hotel | ||
|
|
||
| class ReservationManager < Reservation | ||
|
|
||
| attr_reader :rooms, :reservations | ||
|
|
||
| def initialize | ||
| @rooms = build_room_list | ||
| @reservations = [] | ||
| end | ||
|
|
||
| def build_room_list | ||
| rooms = [] | ||
| 20.times do |i| | ||
| rooms << Hotel::Room.new({room_number: "#{i + 1}".to_i, price: 200}) | ||
| end | ||
| return rooms | ||
| end | ||
|
|
||
| def check_dates(check_in, check_out) | ||
| raise ArgumentError if check_out == nil | ||
| raise ArgumentError if check_in == nil | ||
| raise ArgumentError if check_out < check_in | ||
| raise ArgumentError if check_in > check_out | ||
| end | ||
|
|
||
| def find_room(check_in, check_out) | ||
| # find a way to use the find enumerable | ||
| # rm_avail = true | ||
| # @reservations.each do |reservation| | ||
| # if room.room_number == reservation.room.room_number | ||
| # if Date.strptime(check_in, '%m/%d/%Y') >= reservation.check_in && Date.strptime(check_out, '%m/%d/%Y') < reservation.check_out | ||
| # rm_avail = false | ||
| # break | ||
| # end | ||
| # else | ||
| # rm_avail = false | ||
| # end | ||
| # end | ||
| # if rm_avail | ||
| # return room | ||
| # end | ||
| check_in = Date.strptime(check_in, '%m/%d/%Y') | ||
| check_out = Date.strptime(check_out, '%m/%d/%Y') | ||
|
|
||
| unavailable = @reservations.collect do |reservation| | ||
| if check_in >= reservation.check_in && check_in < reservation.check_out | ||
| reservation.room | ||
| end | ||
| end | ||
| if unavailable.length == 20 | ||
| return "No rooms available" | ||
| else | ||
| return @rooms[unavailable.length] | ||
| end | ||
| end | ||
|
|
||
|
|
||
| def create_reservation(check_in, check_out) | ||
| check_dates(check_in, check_out) | ||
| room = find_room(check_in, check_out) | ||
| reservation = Hotel::Reservation.new(room: room, check_in: check_in, check_out: check_out) | ||
|
|
||
|
|
||
| if reservation.room.room_number < 1 && reservation.room.room_number > 20 | ||
| raise ArgumentError | ||
| end | ||
| @reservations << reservation | ||
| return reservation | ||
| end | ||
|
|
||
| def get_total(room, check_in, check_out) | ||
| @reservations.each do |reservation| | ||
| if reservation.room.nil? || reservation.room.room_number < 1 || reservation.room.room_number > 20 | ||
| raise ArgumentError | ||
| elsif reservation.room.room_number == room | ||
| if check_in != reservation.check_in || check_out != reservation.check_out | ||
| raise ArgumentError | ||
| else | ||
| date = reservation.check_out - reservation.check_in | ||
| price = reservation.room.price | ||
| return price * date | ||
| end | ||
| end | ||
| end | ||
| end | ||
|
|
||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| require 'time' | ||
|
|
||
| module Hotel | ||
|
|
||
| class Room | ||
| attr_accessor :room_number | ||
| attr_reader :price | ||
|
|
||
| def initialize(input) | ||
| @room_number = input[:room_number] | ||
| if @room_number < 1 || @room_number > 20 | ||
| raise ArgumentError | ||
| end | ||
| @price = input[:price] | ||
| if @price != 200 | ||
| raise ArgumentError | ||
| end | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| 1. Move ArgumentErrors to check_dates method | ||
|
|
||
| 2. Refactor find_rooms method - make a new method to minimize nested loops | ||
|
|
||
| 3. Build rooms before creating reservation_mngr instances | ||
|
|
||
| 4. Change name of "rez" in reservation_mngr test ln 64 | ||
|
|
||
| 5. Change name of "@rez" in reservation_mngr test ln 46 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| require_relative 'spec_helper' | ||
|
|
||
| require 'date' | ||
|
|
||
| describe 'ReservationManager class' do | ||
|
|
||
| describe "ReservationManager instantiation" do | ||
| before do | ||
| @room = Hotel::Room.new( {room_number: 1, price: 200} ) | ||
|
|
||
| @res_1 = Hotel::Reservation.new( { room: @room, check_in: "01/10/1988", check_out: "01/17/1988"} ) | ||
|
|
||
| @front_desk = Hotel::ReservationManager.new() | ||
| end | ||
|
|
||
| it "is an instance of ReservationManager" do | ||
| expect(@front_desk).must_be_kind_of Hotel::ReservationManager | ||
| end | ||
|
|
||
| it "is set up for specific attributes and data types" do | ||
| [:rooms, :reservations].each do |prop| | ||
| expect(@front_desk).must_respond_to prop | ||
| end | ||
|
|
||
| expect(@front_desk.rooms).must_be_kind_of Array | ||
| expect(@front_desk.reservations).must_be_kind_of Array | ||
| end | ||
| end | ||
|
|
||
| describe "build_room_list" do | ||
| before do | ||
| @front_desk = Hotel::ReservationManager.new() | ||
| @room_list = @front_desk.build_room_list | ||
| end | ||
|
|
||
| it "returns an array length of 20" do | ||
| expect(@room_list.length).must_equal 20 | ||
| end | ||
| end | ||
|
|
||
| describe "find_room" do | ||
| before do | ||
| @front_desk = Hotel::ReservationManager.new() | ||
| @room_list = @front_desk.build_room_list | ||
| @front_desk.find_room("01/03/2018", "01/10/2018") | ||
|
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 method gets called, but it doesn't change anything and the return value doesn't get stored anywhere! Do we need this line? |
||
| end | ||
|
|
||
| it "returns a room that's available" do | ||
| res_1 = @front_desk.create_reservation("01/03/2018", "01/10/2018") | ||
|
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. Even though the method |
||
| expect(res_1.room.room_number).must_equal 1 | ||
| end | ||
|
|
||
| it "returns next available room" do | ||
| @res_1 = @front_desk.create_reservation("01/03/2018", "01/10/2018") | ||
| @res_2 = @front_desk.create_reservation("01/03/2018", "01/07/2018") | ||
| expect(@res_2.room.room_number).must_equal 2 | ||
| end | ||
|
|
||
| it "returns length of array when all rooms reserved" do | ||
| 20.times do |i| | ||
| @front_desk.create_reservation("01/03/2018", "01/10/2018") | ||
| end | ||
| rez = @front_desk.reservations | ||
| expect(rez.length).must_equal 20 | ||
| end | ||
|
|
||
| end | ||
|
|
||
|
|
||
| describe "create_reservation" do | ||
| before do | ||
| @room = Hotel::Room.new( {room_number: 1, price: 200} ) | ||
| @front_desk = Hotel::ReservationManager.new() | ||
| end | ||
|
|
||
| it "throws an ArgumentError if check_out is before check_in" do | ||
| expect{@front_desk.create_reservation("01/10/2018", "01/09/2018")}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "throws an ArgumentError if check_in is after check_out" do | ||
| expect{@front_desk.create_reservation("01/18/1988", "01/17/1988")}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "throws an ArgumentError if check_in is nil" do | ||
| expect{@front_desk.create_reservation(nil, "01/17/1988")}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "throws an ArgumentError if check_out is nil" do | ||
| expect{@front_desk.create_reservation("01/18/1988", nil)}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "throws an ArgumentError if check_in and check_out are both nil" do | ||
| expect{@front_desk.create_reservation(nil, nil)}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "stores reservation instance to class variable - reservations" do | ||
| @front_desk.create_reservation("01/10/2018", "01/17/2018") | ||
| res = @front_desk.reservations.length | ||
| expect(res).must_equal 1 | ||
| end | ||
|
|
||
| it "returns a reservation" do | ||
| expect(@front_desk.create_reservation("01/10/2018", "01/17/2018")).must_be_kind_of Hotel::Reservation | ||
| end | ||
| end | ||
|
|
||
| describe "get_total" do | ||
| before do | ||
| @front_desk = Hotel::ReservationManager.new() | ||
| @front_desk.create_reservation("01/10/1988", "01/17/1988") | ||
| end | ||
|
|
||
| it "calculates total cost of reservation" do | ||
| expect(@front_desk.get_total(1, Date.strptime("01/10/1988", '%m/%d/%Y'), Date.strptime("01/17/1988", '%m/%d/%Y') ) ).must_equal 1400 | ||
|
|
||
| @front_desk.create_reservation("01/15/1988", "01/20/1988") | ||
|
|
||
| expect(@front_desk.get_total(2, Date.strptime("01/15/1988", '%m/%d/%Y'), Date.strptime("01/20/1988", '%m/%d/%Y') ) ).must_equal 1000 | ||
| end | ||
| 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.
@reservationsstores all of the reservations made in the whole system. Why does it throw an error if there are more than 20?For example, what if I made 20 non-conflicting reservations for different dates? Should there be an error thrown when I made the 21st reservation?