Skip to content

Space - Nora#20

Open
thenora wants to merge 30 commits intoAda-C13:masterfrom
thenora:master
Open

Space - Nora#20
thenora wants to merge 30 commits intoAda-C13:masterfrom
thenora:master

Conversation

@thenora
Copy link

@thenora thenora commented Mar 9, 2020

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? The first couple days of the project I got stuck in a cycle of changing where methods should live between classes. I went back to pen and paper and sketched out the relationship between the classes again and wrote out all the methods and variables so I could see how they related to each other.
What was a design decision you made that changed over time over the project? I initially started with a rooms class, but never ended up using it.
What was a concept you gained clarity on, or a learning that you'd like to share? Within the first couple days I was having trouble understanding how some classes related to each other. I had an a-ha moment when I realized that instantiating one class could require an instantiation of a different class. Things really clicked into place after that.
What is an example of a nominal test that you wrote for this assignment? What makes it a nominal case? An example of a nominal test is making sure the reserve_room function in the FrontDesk class actually makes a reservation. "expect(@reserved).must_be_kind_of Hotel::Reservation" This would be an expected positive use case.
What is an example of an edge case test that you wrote for this assignment? What makes it an edge case? I wrote several edge cases for the DateRange class constuctor, including "raises an error if the end date is before the start date" This is an edge case because it's not expected typical use, but something that could be something we'd need to anticipate.
How do you feel you did in writing pseudocode first, then writing the tests and then the code? I wasn't always great about starting with pseudocode, but I definitely used it whenever I was stuck or needed to think through a more complicated method. It often helped me decide if I wanted to split something into multiple methods.

@kaidamasaki
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 No mention of TDD in reflection.
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 Only tests a single reservation.
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 Not implemented.
reserves a room from a block Not implemented.

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 commented your code with your user stories and especially that you mentioned things like breaking a story into multiple methods. That was really thoughtful and clear.

I do see some room for improvement around little things, mostly code style stuff. When you make your code more concise it can help make many bugs more obvious. (See inline comments.)

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

@end_date = end_date
@dates = Array(@start_date .. @end_date)

# User: I want an exception raised when an invalid date range is provided, so that I can't make a reservation for an invalid date range

Choose a reason for hiding this comment

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

I like including the user stories as comments. 😄


# User: I want an exception raised when an invalid date range is provided, so that I can't make a reservation for an invalid date range
if @end_date < @start_date || @start_date == @end_date
raise ArgumentError.new("Your check-out date must be after your check-in.")

Choose a reason for hiding this comment

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

It's helpful to include the bad arguments in your error messages:

Suggested change
raise ArgumentError.new("Your check-out date must be after your check-in.")
raise ArgumentError.new("Your check-out date (#{@start_date}) must be after your check-in (#{end_date}).")

Comment on lines +18 to +19
overlap = !(daterange_instance.start_date >= end_date || daterange_instance.end_date <= start_date)
return overlap

Choose a reason for hiding this comment

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

You don't have to assign this to a variable before you return it:

Suggested change
overlap = !(daterange_instance.start_date >= end_date || daterange_instance.end_date <= start_date)
return overlap
return !(daterange_instance.start_date >= end_date || daterange_instance.end_date <= start_date)

Also, you can simplify/clarify this using DeMorgan's Law and reversing the comparisons:

Suggested change
overlap = !(daterange_instance.start_date >= end_date || daterange_instance.end_date <= start_date)
return overlap
return daterange_instance.start_date < end_date && daterange_instance.end_date > start_date

Comment on lines +23 to +27
if date >= @start_date && date < @end_date
return true
else
return false
end

Choose a reason for hiding this comment

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

You can directly return the condition here:

Suggested change
if date >= @start_date && date < @end_date
return true
else
return false
end
return date >= @start_date && date < @end_date

attr_accessor :reservations, :rooms, :calendar

def initialize
@rooms = (1..20).map { |i| i }

Choose a reason for hiding this comment

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

It looks like you're just using map to convert this to an array. You can use to_a for that:

Suggested change
@rooms = (1..20).map { |i| i }
@rooms = (1..20).to_a

Comment on lines +14 to +24
def populate_calendar(reservation)
temp = reservation.date_range.dates
temp.pop
temp.each do |date|
if !@calendar.key?(date)
@calendar[date] =[]
end
@calendar[date] << reservation
end
return @calendar
end

Choose a reason for hiding this comment

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

I think you probably meant to copy the array here. This doesn't do that so you wind up changing dates.

Cleaner would be to ask for a range that excludes the end of dates (you can also use an unless to tidy up your condition):

Suggested change
def populate_calendar(reservation)
temp = reservation.date_range.dates
temp.pop
temp.each do |date|
if !@calendar.key?(date)
@calendar[date] =[]
end
@calendar[date] << reservation
end
return @calendar
end
def populate_calendar(reservation)
reservation.date_range.dates[0...-1].each do |date|
unless @calendar.key?(date)
@calendar[date] = []
end
@calendar[date] << reservation
end
return @calendar
end

Choose a reason for hiding this comment

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

Also, since this method doesn't directly address a user story I'd recommend making it private.

Comment on lines +27 to +29
def list_rooms
return @rooms
end

Choose a reason for hiding this comment

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

You don't need this and the attr_accessor for @rooms. I'd recommend picking one or the other.

Comment on lines +55 to +65
def range_reservations(requested_dates)
range_resv = []
requested_dates.dates.each do |date|
if @calendar.key?(date)
range_resv.push(*@calendar[date])
end
end
range_resv = range_resv.uniq

return range_resv
end

Choose a reason for hiding this comment

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

You can clean this up using select and flat_map:

Suggested change
def range_reservations(requested_dates)
range_resv = []
requested_dates.dates.each do |date|
if @calendar.key?(date)
range_resv.push(*@calendar[date])
end
end
range_resv = range_resv.uniq
return range_resv
end
def range_reservations(requested_dates)
return requested_dates.dates.select do |date|
@calendar.key?(date)
end.flat_map do |date|
@calendar[date]
end.uniq
end

(Since it's kind of obscure: flat_map is equivalent to doing a map followed by a flatten. It basically says "go through the input and produce an array out of the little arrays this block outputs".)

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