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

Amy Cash - Pipes - Hotel #33

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

Amy Cash - Pipes - Hotel #33

wants to merge 48 commits into from

Conversation

cashmonger
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? Whether there should be a room class. I thought a lot about what I needed from that class -- would it just give me a list of rooms? If so, then that function could probably be part of hotel/reservation instead. We discussed this in our group, but I still didn't feel happy with that set up until I started actually working on it and couldn't see what extra use having a separate room class would be. I'm not really happy with how I set up blocks. The class I set up isn't really doing much of anything and if I had more time, I'd rethink how to set this up.
Describe a concept that you gained more clarity on as you worked on this assignment. Keyword Arguments! I struggled with using them in methods where one method was calling another method, usually in another class, so learning to set that up was an informative struggle.
Describe a nominal test that you wrote for this assignment. Testing whether each class could be instantiated
Describe an edge case test that you wrote for this assignment. I'm not sure I did write any? I'm realizing in looking over my tests, that I'm not sure what "edge case" means in this context. It's easier for me to picture in terms of a user interface (e.g. "what happens if the administrator enters nothing", but I wasn't making that part here. I did test for things like their being no rooms available in a block, but does that count as an edge case?
How do you feel you did in writing pseudocode first, then writing the tests and then the code? I found this very helpful, both in keeping straight what I was a trying to do with each method and clarifying my thinking about how methods and classes would/could interact

@droberts-sea
Copy link

Hotel

What We're Looking For

Feature Feedback
Baseline
Used git regularly yes - good work!
Answer comprehension questions yes
Design
Each class is responsible for a single piece of the program some - While your other classes keep track of state, it seems like your Hotel class has ended up responsible for most of the behavior of your application.
Classes are loosely coupled mostly - I've pointed out areas inline where I noticed tight coupling.
Wave 1
List rooms yes
Reserve a room for a given date range yes
List reservations for a given date yes
Calculate reservation price yes
Invalid date range produces an error yes
Test coverage missing some around finding reservations
Wave 2
View available rooms for a given date range yes
Reserving a room that is not available produces an error yes
Test coverage missing some about checking reservation conflicts
Wave 3
Create a block of rooms yes
Check if a block has rooms yes
Reserve a room from a block yes
Test coverage yes
Additional Feedback

Good work overall. The big thing I notice missing is test coverage around checking which rooms are reserved when. The logic is quite complex and it's also hidden within other functionality, which makes it difficult to test explicitly. This sort of scenario is where design work starts to pay off - by isolating behaviors like comparing two date ranges, you can test them without all the overhead of hotels and reservations, as the foundational units of your application. For an example of how design can make testing easier, you should check out our reference implementation.

That being said, I'm pretty happy with what you've submitted. Your design is clear and intentional, and your code is well-organized and easy to read. Keep up the good work!


def self.check_dates(first, last)
if Date.parse(first) > Date.parse(last)
raise ArgumentError, "Check Out Date is earlier than Check in Date"

Choose a reason for hiding this comment

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

Is it valid if first == last?


class DateRange

attr_reader :check_in, :check_out, :date_range

Choose a reason for hiding this comment

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

You never instantiate this class! You're basically using it as a library of methods to work with dates, which means it might be clearer as a module.


def make_reservation(id, day_in, day_out, discount: 0, block_name: nil, room: 0)
available = open_rooms(day_in, day_out)
if room == 0

Choose a reason for hiding this comment

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

Since room number is an integer, it might make more sense to use a non-integer sentinel value here. nil is usually a good choice.

lib/hotel.rb Outdated
DateRange.check_dates(day_in, day_out)
DateRange.create_range(day_in, day_out).each do |date|
found_reservations << all_reservations.find_all { |reservation| reservation.nights_reserved.include?(Date.parse(date)) }
end #each date

Choose a reason for hiding this comment

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

This is an example of tight coupling between Hotel and Reservation. Peeking into reservation.nights_reserved means that if that implementation ever changes, this code will need to change too. Instead, it might be cleaner to write a method Reservation#includes_date, and call it here.

if reservation.id == reservation_id
return reservation.total_cost
else
return "Reservation Not Found"

Choose a reason for hiding this comment

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

This would be a good place to raise an error. Maybe a custom NoSuchReservationError?

elsif room != 0 && available.include?(room)
first_open = room
else
raise ArgumentError, "Requested Room is Not Available during Date Range"

Choose a reason for hiding this comment

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

I'm not sure an ArgumentError is the right call here. That usually indicates the arguments are invalid (i.e. a bogus room number or date range) or not of the right type, but that's not what this error is describing. Maybe this would be a good place to use a custom exception.

describe "DateRange Class" do
before do
@date_test = Hotel::DateRange.new
end #before

Choose a reason for hiding this comment

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

You don't have any tests around check_dates!

@hotel.make_reservation(2224, "2012/12/13", "2012/12/17")
@hotel.open_rooms("2012/12/12", "2012/12/13").must_be_kind_of Array
@hotel.open_rooms("2012/12/12", "2012/12/13")[0].must_equal 3
end #open rooms

Choose a reason for hiding this comment

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

Other cases I'd be interested in:

  • What if there are no reservations? (it should return an empty array)
  • Do reservations that don't overlap the date range affect the list? (they shouldn't)
    • Check the boundaries of what counts as an overlap. What about a reservation that ends on the checkin date, or starts on the checkout date?

proc {
@hotel.make_reservation(1000, "2001/1/30", "2001/2/4", room: 1)
}.must_raise ArgumentError
end

Choose a reason for hiding this comment

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

This is a good start, but I'd like to see more coverage around what date ranges will conflict with each other. Cases I'd be interested in:

  • Not available:
    • Same dates
    • Overlaps in the front
    • Overlaps in the back
    • Completely contained
    • Completely containing
  • Available:
    • Completely before
    • Completely after
    • Ends on the checkin date
    • Starts on the checkout date


describe "Blocks" do

it "Can call Block to create an array to store block information" do

Choose a reason for hiding this comment

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

Test coverage looks pretty good around blocks. There are just a couple of places where it seems like things are missing:

  • What happens if you try to create a block when there are not enough rooms available?
  • What if the dates on the reservation don't match those on the block?

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