Skip to content
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

goeun - edges - hotel #22

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open

goeun - edges - hotel #22

wants to merge 30 commits into from

Conversation

goeunpark
Copy link

Hotel

Congratulations! You're submitting your assignment!

Comprehension Questions

Question Answer
Describe a design decision you had to make when working on this project. What options were you considering? What helped you make your final decision? I initially over-designed and my classes had too much dependency (rooms knew which reservations they were associated with) and I thought I would create a lot more data structures than necessary (a whole array in HotelBooker for all the dates ever booked). Thinking about how Chapter 3 Sandi Metz would be unimpressed with my agenda helped. Having a looming deadline made me feel rushed so I went with options that felt like it would let me get away with bare minimum. In retrospect, that was a pretty good design plan.
Describe a concept that you gained more clarity on as you worked on this assignment. HotelBooker is my factory class. Initially, I had Reservations create Rooms and Rooms refer to DateRanges but then it got too messy so I put all the logic into my main class. I see now that TripDispatcher in Rideshare was set up to instantiate all the objects for a reason!
Describe a nominal test that you wrote for this assignment. I created one reservation for one date range (lines 32 - 41 in HotelBooker). Easy. Things seemed to work.
Describe an edge case test that you wrote for this assignment. I created 20 reservations for one date range (lines 43 - 49 in HotelBooker). Then I tried to create one more. But there were no more available rooms, so I raised an StandardError
How do you feel you did in writing pseudocode first, then writing the tests and then the code? Feel pretty good about writing pseudocode! I feel like I was A LOT better at git hygiene and TDD with a partner. Will work on it

…t; test for find_reservations(date) in hotel_booker is red
@tildeee
Copy link

tildeee commented Sep 21, 2018

Hotel

What We're Looking For

Feature Feedback
Baseline
Used git regularly x
Answer comprehension questions x
Design
Each class is responsible for a single piece of the program x
Classes are loosely coupled x
Wave 1
List rooms x
Reserve a room for a given date range x
List reservations for a given date x
Calculate reservation price x
Invalid date range produces an error x
Test coverage x
Wave 2
View available rooms for a given date range x
Reserving a room that is not available produces an error x
Test coverage x
Wave 3
Create a block of rooms x
Check if a block has rooms x
Reserve a room from a block x
Test coverage x
Fundamentals
Names variables, classes and modules appropriately x, fantastic!
Understanding of variable scope - local vs instance x
Can create complex logical structures utilizing variables x
Appropriately uses methods to break down tasks into smaller simpler tasks x
Understands the differences between class and instance methods x
Appropriately uses iterators and enumerables x
Appropriately writes and utilizes classes x
Appropriately utilizes modules as a mechanism to encapsulate functionality x
Wrap Up
There is a refactors.txt file x
The file provides a roadmap to future changes x
Additional Feedback

Goeun! Good job with this project!

I think that your code looks good-- I think that your design is pretty good-- your HotelBooker manages the reservations, rooms, reserved blocks, and unreserved blocks. The complex date overlap logic lives in the DateRange class, which I think really paid off.

Overall, my biggest comment is that I truly feel that the tests were thorough, clean, and readable. I in fact have very little comments on the tests because I think they're great-- wish I had more to comment on, but I really think you did a great job on the tests!

That being said, I'm adding some comments on specific pieces of code. The main themes on these comments are:

  1. Suggestions for minor refactorings to clean up code style
  2. Weirdly enough, I think you're pretty inconsistent with checking if an array is empty, so I'm calling that out a little specifically??

In conclusion: generally good job! I think I could see your code being a tiny bit cleaner, but the DateRange decision and the tests you wrote are really great and overwhelmingly positive.

class HotelBooker
attr_accessor :rooms, :reservations, :unreserved_block, :reserved_block
NUM_ROOMS = 20
BLOCK_MAX = 5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES CONSTANTS

@rooms = []

NUM_ROOMS.times do |i|
@rooms << Hotel::Room.new(i+1)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ruby will be looking for names locally first, prioritizing local names... so, since they're all in the same module, there's no need to namespace Hotel::Room... Room should just work! Same with the rest of the namespacing in the code.

check_in = Date.parse(check_in)
check_out = Date.parse(check_out)
date_range = range(check_in, check_out)
reservation = Hotel::Reservation.new(id, date_range)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might give you less "overusing the word range"-anxiety to in-line this:

reservation = Hotel::Reservation.new(id, range(check_in, check_out))

available = unreserved_rooms(check_in, check_out)
if available == []
raise StandardError, "There are no more available rooms for this date range!"
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably reads better to write this as if available.empty?, or maybe inline it somehow ;)

end


def make_block(rooms: nil, discount: nil, check_in: nil, check_out: nil)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This keyword args syntax makes these parameters optional: is that what you want?

def make_block_reservation(id)
if @unreserved_block.length == 0
raise StandardError, "There are no available Block reservations."
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is another block of code that checks if an array is empty in a different way? If so -- check my comment above!

unreserved_block_rooms = []
@unreserved_block.each do |reservation|
unreserved_block_rooms << reservation.room
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could possibly be a good chance to use map

if reservation_dates.include?(date)
matching_reservations << reservation
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using .each, might be good opportunity to use select

@@ -0,0 +1,7 @@
1. I...lowkey cheated and made a collection of Reservations instead of a collection of Rooms. I would rewrite this part by making a subclass under Room called BookedRoom?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure what you mean by this tbh!

@@ -0,0 +1,7 @@
1. I...lowkey cheated and made a collection of Reservations instead of a collection of Rooms. I would rewrite this part by making a subclass under Room called BookedRoom?

2. HotelBooker has a lot of WET code because I have to loop through several data structures (@unreserved_block, @reserved_block, @reservations)!! If I had focused the Wave 3 blocks of rooms on the ROOMS instead of reservations, probably wouldn't have created this mess ¯\_(ツ)_/¯
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


2. HotelBooker has a lot of WET code because I have to loop through several data structures (@unreserved_block, @reserved_block, @reservations)!! If I had focused the Wave 3 blocks of rooms on the ROOMS instead of reservations, probably wouldn't have created this mess ¯\_(ツ)_/¯

3. there are certain check_in and check_out arguments that are strings (as in Hotel::HotelBooker.new.make_reservation) and some that are an instance of Date (as in Hotel::HotelBooker.new.unreserved_rooms). Other arguments pass in a Hotel::DateRange (such as Hotel::Reservations). note to future goeun: make this less terrible
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would absolutely agree with this

expect(@date_range2.overlaps?(@date_range4)).must_equal false
end
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this DateRange class because it isolated the overlapping date logic to this one class, which is complex and tested in isolation... Beautiful :* truly inspiring :*

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants