Skip to content

Conversation

@easternwashingaden
Copy link

Assignment Submission: Hotel

Congratulations! You're submitting your assignment. Please reflect on the assignment with these questions.

Reflection

Question Answer
What was a design challenge that you encountered on this project? When first started the project, I was not sure where to store all the room and reservations. I used the design scaffolding to start designing the program. When I started working on Wave 3, it made more sense. I did learn so much from this project.
What was a design decision you made that changed over time over the project? When I worked on Wave 3, since now we have the hotel_blocks, I had to change the available_rooms from Wave 2. To check for available_rooms, we now have to check not only for the rooms that have been reserved in reservations, but also we have to check if the rooms is a part of the hotel_block. I also created a lot of method helpers to help with other methods, so one method doesn't become too long and try to do anything a time.
What was a concept you gained clarity on, or a learning that you'd like to share? When I tried to compare two objects, for example hotel_block.date_range == specific_date_range. Object.new == Object.new # false. The reason Object returns false is because two new objects have different object id’s. I can define exactly what it means for two instances of its own class to be equal. That means, hotel_block. In my DateRange class, I created a method date_range == specific_date_range as long as they have the same start_date and end_date. def ==(other) self.start_date == other.start_date && self.end_date == other.end_date end
What is an example of a nominal test that you wrote for this assignment? What makes it a nominal case? Reservation Id must be a positive integer, I expected to see ArgumentError raised when I passed id = "kdkjfkdaj".
What is an example of an edge case test that you wrote for this assignment? What makes it an edge case? The maximum of rooms is 5, rooms.length > 5. When I tried to crate a hotel_block where there were 6 rooms in the rooms_array, I expect to see ArgumentError raised.
How do you feel you did in writing pseudocode first, then writing the tests and then the code? It is really helpful because I know better what the requirements are before starting writing the codes. I have learned so much from this project, especially it made me feel more comfortable writing more tests.

Dan Roberts and others added 27 commits July 25, 2019 15:57
Design Scaffolding for the Hotel project
@dHelmgren
Copy link

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 ✔️

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 grouped data into well thought out classes and thoroughly tested all parts of your program. Testing is a tough skill to master, but your tests cover your code very well, and also explain the reasons for each test clearly! Also, the way you broke up data between the different classes showed a lot of forethought on your part, letting each class represent a unique and tightly clustered set of values.

I do see some room for improvement around grouping functionality under the appropriate class. Specifically, I left comments on how your HotelBlock class seems a bit too small to justify itself, and how your HotelController seems to have methods that do work that could belong to some other class. My generic advice here is that if you are calling a series of methods and you have 2 or more .s in the call, you might want to consider moving that method into the class or classes that you are 'reaching through'.

Here are the warnings your code produces:

/Users/devin/Documents/Ada/c13/hotel/test/date_range_test.rb:17: warning: `-' after local variable or literal is interpreted as binary operator
/Users/devin/Documents/Ada/c13/hotel/test/date_range_test.rb:17: warning: even though it seems like unary operator
/Users/devin/Documents/Ada/c13/hotel/lib/hotel_controller.rb:51: warning: assigned but unused variable - reservations_list_by_date_range
/Users/devin/Documents/Ada/c13/hotel/lib/hotel_controller.rb:57: warning: assigned but unused variable - given_date_range
/Users/devin/Documents/Ada/c13/hotel/lib/hotel_controller.rb:71: warning: assigned but unused variable - given_date_range
/Users/devin/Documents/Ada/c13/hotel/lib/hotel_controller.rb:176: warning: assigned but unused variable - all_available_rooms_of_hotel_blocks
/Users/devin/Documents/Ada/c13/hotel/lib/hotel_controller.rb:226: warning: mismatched indentations at 'end' with 'def' at 208
/Users/devin/Documents/Ada/c13/hotel/lib/reservation.rb:15: warning: assigned but unused variable - total_cost
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:199: warning: assigned but unused variable - new_hotel_block
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:221: warning: assigned but unused variable - reservation1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:270: warning: assigned but unused variable - reservation1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:278: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:291: warning: assigned but unused variable - new_hotel_block
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:309: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:310: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:327: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:328: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:364: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:365: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:379: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:380: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:397: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:398: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:412: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:413: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:431: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:432: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:446: warning: assigned but unused variable - new_hotel_block1
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:447: warning: assigned but unused variable - new_hotel_block2
/Users/devin/Documents/Ada/c13/hotel/test/hotel_controller_test.rb:497: warning: assigned but unused variable - new_hotel_block1

Code Style Bonus Awards

Was the code particularly impressive in code style for any of these reasons (or more...?)

Quality Yes?
Elegant/Clever
Logical/Organized

Comment on lines +2 to +10
class HotelBlock
attr_reader :date_range , :rooms , :discounted_rate
def initialize(date_range, rooms, discounted_rate)
@date_range = date_range
raise ArgumentError.new("A block can contain a maximum of 5 rooms") if rooms.length > 5
raise ArgumentError.new("The hotel block cannot be made without having a room") if rooms.empty?
@rooms = rooms
@discounted_rate = 0.1
end

Choose a reason for hiding this comment

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

A class that only has an initialize method is usually a sign that this didn't need to be a fully fledged class. With this method, it seems like you could have done the work of the HotelBlock class using a hash instead.

Sometimes what this means is that you are letting the wrong class take on responsibilities that belong to this data.

Comment on lines +2 to +3
class NoRoomAvailableError < StandardError
end

Choose a reason for hiding this comment

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

This doesn't have to be in it's own file! :)

Comment on lines +15 to +17
def ==(other)
self.id == other.id
end

Choose a reason for hiding this comment

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

Nice work overwriting this method!

Comment on lines +7 to +19
@room1 = Hotel::Room.new(1, 200)
@room2 = Hotel::Room.new(2, 200)
@room3 = Hotel::Room.new(3, 200)
@room4 = Hotel::Room.new(4, 200)
@room5 = Hotel::Room.new(5, 200)
@room6 = Hotel::Room.new(6, 200)
@room_array1 = [@room1, @room2]
@room_array2 = [@room1,@room2,@room3,@room4,@room5,@room6]
@room_array3 = []
@start_date = Date.today
@end_date = @start_date + 3
@date_range = Hotel::DateRange.new(@start_date,@end_date)
@discount_rate = 0.1

Choose a reason for hiding this comment

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

Do you need all of this data before each test?

Comment on lines +58 to +84
it "returns true for a range that overlaps in the back" do
start_date = Date.new(2017, 02, 02)
end_date = start_date + 10
test_range = Hotel::DateRange.new(start_date, end_date)
expect(@range.overlap?(test_range)).must_equal true
end

it "returns true for a containing range" do
start_date = Date.new(2017, 02, 02)
end_date = start_date + 1
test_range = Hotel::DateRange.new(start_date, end_date)
expect(@range.overlap?(test_range)).must_equal true
end

it "returns false for a range starting on the end_date date" do
start_date = Date.new(2017, 02, 04)
end_date = start_date + 10
test_range = Hotel::DateRange.new(start_date, end_date)
expect(@range.overlap?(test_range)).must_equal false
end

it "returns false for a range ending on the start_date date" do
start_date = Date.new(2017, 01, 28)
end_date = Date.new(2017, 02, 01)
test_range = Hotel::DateRange.new(start_date, end_date)
expect(@range.overlap?(test_range)).must_equal false
end

Choose a reason for hiding this comment

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

Love how thorough your tests are!

end

describe "cost" do
it "returns a number" do

Choose a reason for hiding this comment

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

This isn't a great name for this test, because you are also checking the value of that number. I'd write

Suggested change
it "returns a number" do
it "returns the correct cost as a Number" do

Comment on lines +194 to +198
def remove_room_from_hotel_block(room, start_date, end_date)
specific_hotel_block = specific_hotel_block(room, start_date, end_date)
specific_hotel_block.rooms.delete(room)
return specific_hotel_block
end

Choose a reason for hiding this comment

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

This seems like something the HotelBlock should be in charge of to me.

Comment on lines +150 to +156
def available_rooms_of_block(hotel_block)
if hotel_block.rooms.empty?
raise ArgumentError.new("The hotel block cannot be made without having a room")
else
return hotel_block.rooms
end
end

Choose a reason for hiding this comment

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

This method also seems like something the HotelBlock should be in charge of. if it were in the HotelBlock, it might look like this

Suggested change
def available_rooms_of_block(hotel_block)
if hotel_block.rooms.empty?
raise ArgumentError.new("The hotel block cannot be made without having a room")
else
return hotel_block.rooms
end
end
def available_rooms
if self.rooms.empty?
raise ArgumentError.new("The hotel block cannot be made without having a room")
else
return rooms
end
end

Moving this code both makes HotelController easier to read, and makes for fewer chained method calls.

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.

4 participants