Skip to content

Ports - Faiza#26

Open
Faiza1987 wants to merge 22 commits intoAda-C11:masterfrom
Faiza1987:master
Open

Ports - Faiza#26
Faiza1987 wants to merge 22 commits intoAda-C11:masterfrom
Faiza1987:master

Conversation

@Faiza1987
Copy link
Copy Markdown

@Faiza1987 Faiza1987 commented Mar 18, 2019

Hotel

Congratulations! You're submitting your assignment!

Comprehension Questions

Question Answer
What was a design challenge that you encountered on this project? I was unsure at first how many classes I would need. I re-designed my project twice before getting to Wave 3, and then redesigned it again because it made some of the previous classes redundant.
What was a design decision you made that changed over time over the project? I started out with having a Room class that I decided to scrap because it was not doing anything at all and was not communicating with any other classes.
What was a concept you gained clarity on, or a learning that you'd like to share? I discovered that I should keep a bigger view of the project in mind while writing the basic functionality so that it is easier to refactor and fits better in the larger scheme of things.
What is an example of a nominal test that you wrote for this assignment? What makes it a nominal case? I wrote a test to make sure that there were no more than 20 elements in the @all_rooms array
What is an example of an edge case test that you wrote for this assignment? What makes it an edge case? I wrote a test that would raise an ArgumentError if the check_out date was earlier than the current date.
How do you feel you did in writing pseudocode first, then writing the tests and then the code? I wrote pseudocode for the larger project and for individual methods which on paper seemed it would work very well but I had to deviate from the pseudocode while writing the actual code to get the desired results.

…e method in Main.rb. Got previous failing tests working and wrote a new test test that is bith failing and passing when guard is run multiple times. Need to fix.
…les. Made FrontDesk a Class again. Modiefied tests by instantiating FrontDesk in each describe block
…sponding tests as well. Added .round to total_cost
…eservation method to check for overlapping dates for room reservations and to raise error if dates overlap.
…lass. Created a class called BlockRoom for Wave 3. Class has been tested.
@tildeee
Copy link
Copy Markdown

tildeee commented Mar 23, 2019

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 you made reservations and hotel blocks the same thing, when their state and behaviors are actually quite different
Classes are loosely coupled in some ways, you set this up well by making helper methods like reservation_template. However, in your tests, you didn't use keyword arguments
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 largely there
Wave 2
View available rooms for a given date range x
Reserving a room that is not available produces an error x
Test coverage largely there, missing some test cases
Wave 3
Create a block of rooms x, with misinterpretation (made block of rooms a kind of reservation)
Check if a block has rooms x, with misinterpretation
Reserve a room from a block x, with misinterpretation
Test coverage largely there
Fundamentals
Names variables, classes and modules appropriately x
Understanding of variable scope - local vs instance there were many instances of instance variables being used incorrectly: in contexts in which they had nil value
Can create complex logical structures utilizing variables x
Appropriately uses methods to break down tasks into smaller simpler tasks x, but there were many more opportunities to make more helper methods
Understands the differences between class and instance methods x
Appropriately uses iterators and Enumerable methods there was a huge red flag on this: 100% of the time that you could have used an each loop you didn't, and your code became less readable and more confusing because of it. Please reach out if you are unsure how to use an each loop. Similarly, you can even push this skill and use Enumerable methods to make it even cleaner, but you didn't get to do that either
Appropriately writes and utilizes classes x
Appropriately utilizes modules as a namespace x
Wrap Up
There is a refactors.txt file x
The file provides a roadmap to future changes x
Additional Feedback

Good work on this, Faiza-- your design overall ended up to be pretty good, and your tests were full

However, I have a huge concern about some of your code style.

You relied on nesting a lot of ifs/elsifs/elses inside of nested loops, and more loops! With a little thought about how to refactor, you can get rid of a lot of complexity. Similarly, parts of your logic felt strange: what is a first_room_no? Etc.

Similarly, there were a lot of misses on some requirements because of how you implemented room blocks. Room Blocks are not a type of reservation-- even if it may seem like they are.

A lot of my comments are on the following things:

  • Simplify your logic-- watch your nesting
  • Use each loops instead of for loops
  • Misunderstanding about how instance variables work
  • Confirm that what you're doing follows the requirements!
  • You have pretty good tests, but there are areas it could improve

I would love to see improvements on all of these areas, especially the each loops, in the near future

Good work on pushing through this project-- your project could definitely grow and improve, but overall you have a submission that got through all the waves.

Comment thread lib/block_room.rb
attr_accessor :room_booking_ref, :block_room_number, :check_in, :check_out

def initialize(room_booking_ref:, block_room_number:, check_in:, check_out:)
@room_booking_ref = room_booking_ref
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is this variable? Was there a requirement for it?

Comment thread lib/front_desk.rb Outdated
module Hotel
class FrontDesk
# attr_reader :all_rooms, :reservations_record, :block_reservations_only, :reserved_rooms_in_blocks
attr_accessor :all_rooms, :reservations_record, :block_reservations_only, :reserved_rooms_in_blocks
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did you choose to make this accessor instead of reader? Your tests still run the same way if you make it reader, so I would choose this over accessor

Comment thread lib/front_desk.rb

def all_rooms_array
return @all_rooms
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't think this method is wrong-- in fact, it is the perfect example of a "getter method"! However, since what you are returning is an instance variable (@all_rooms), there are ways to refactor this to be shorter and smaller. Think on it and let me know what questions you have :)

Comment thread lib/front_desk.rb
check_out: new_check_out,
total_cost: @total_cost,
room_blocks: @room_blocks,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Here, when you're calling Reservation.new, you are saying that the value that should go into the parameter total_cost should be whatever @total_cost is... but @total_cost doesn't have any value stored on it, ever! You never call @total_cost = ... ever in your code, so it will always be nil.

ame with @room_blocks. @room_blocks is the name of the variable that this instance of FrontDesk has stored, but this instance of FrontDesk will never change that value, so it's always nil. What value were you expecting to be on @room_blocks?

Comment thread lib/front_desk.rb Outdated
if (@reservations_record.length == 0)
booking = reservation_template(new_booking_ref, new_number_of_rooms, new_first_room_number, new_check_in, new_check_out)
else
for i in (0...@reservations_record.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did you choose this for loop instead of an each loop? If you used an each loop, then to refer to each reservation, you can say

@reservations_record.each do |reservation|
            old_first_room_no = reservation.first_room_number
          end

note the difference: reservation, as opposed to @reservations_record[i], so it's a lot shorter and cleaner

Comment thread lib/front_desk.rb Outdated
booking = reservation_template(new_booking_ref, new_number_of_rooms, new_first_room_number, new_check_in, new_check_out)
else
for i in (0...@reservations_record.length)
old_first_room_no = @reservations_record[i].first_room_number
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What does old_first_room_no represent?

Comment thread lib/front_desk.rb Outdated

if ((old_first_room_no >= new_first_room_number && old_first_room_no <= new_last_room_no) ||
(old_last_room_no >= new_first_room_number && old_last_room_no <= new_last_room_no) ||
((old_first_room_no <= new_first_room_number) && (old_first_room_no <= new_last_room_no) && (old_last_room_no >= new_first_room_number) && (old_last_room_no >= new_last_room_no)))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is this logic for?

Comment thread lib/front_desk.rb
booking = reservation_template(new_booking_ref, new_number_of_rooms, new_first_room_number, new_check_in, new_check_out)
end
end
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your variable names and your complex logic here are overwhelming and confusing, and difficult to read. This would be great pulled into helper methods.

Comment thread lib/front_desk.rb Outdated
def get_reservations_by_date(date)
reservations_by_date_list = Array.new

for index in (0...@reservations_record.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For every time you do for i in (0...array.length), it is probably better and more clear to use an each loop

Comment thread lib/front_desk.rb Outdated
reservations_at_date = get_reservations_by_date(date)

available_rooms = Array.new
for room_idx in (0...@all_rooms.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each loop!

Comment thread lib/front_desk.rb Outdated
available_rooms = Array.new
for room_idx in (0...@all_rooms.length)
room_booked = false
for res_idx in (0...reservations_at_date.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each loop!

Comment thread lib/front_desk.rb Outdated
for room_idx in (0...@all_rooms.length)
room_booked = false
for res_idx in (0...reservations_at_date.length)
for i in (0..@reservations_record[res_idx].room_blocks.length - 1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each loop!

Comment thread lib/front_desk.rb
end
end
end
if (room_booked == false)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For something this short, no need to put parens: if room_booked == false or even if !room_booked

Comment thread lib/front_desk.rb
if (room_booked == false)
available_rooms << @all_rooms[room_idx]
end
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This logic isn't clear-- it might be clearer if you iterated through your reservations first, instead of all rooms and then all reservations. However, ultimately, this code isn't readable because of the long variable names and the nested logic. Having a deep "V" nesting (there are 4 levels of nesting) is an indicator that things should be reworked, refactored, and pulled into helper methods.

Comment thread lib/front_desk.rb Outdated

#### BLOCK METHODS ####
def add_block_reservations
for i in (0...@reservations_record.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each loop

Comment thread lib/front_desk.rb
@block_reservations_only << @reservations_record[i]
end
end
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is this method accomplishing? Why do we add to @block_reservations_only every reservation with multiple rooms?

Comment thread lib/front_desk.rb Outdated
end

def make_reservation_in_block(block_room_booking_ref, block_room_number, block_check_in, block_check_out)
for i in (0...@block_reservations_only.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each

Comment thread lib/front_desk.rb Outdated

rooms_in_blocks = Array.new
available_rooms_in_block = Array.new
for i in (0...block_reservations_at_date.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each

Comment thread lib/front_desk.rb Outdated
rooms_in_blocks = Array.new
available_rooms_in_block = Array.new
for i in (0...block_reservations_at_date.length)
for j in (0...block_reservations_at_date[i].room_blocks.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each

Comment thread lib/front_desk.rb Outdated
def block_room_availability(date)
rooms_in_blocks = all_rooms_in_blocks(date)
rooms_available_in_blocks = Array.new
for i in (0...rooms_in_blocks.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each

Comment thread lib/front_desk.rb Outdated
rooms_in_blocks = all_rooms_in_blocks(date)
rooms_available_in_blocks = Array.new
for i in (0...rooms_in_blocks.length)
for j in (0...@reserved_rooms_in_blocks.length)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

each

Comment thread lib/reservation.rb
module Hotel
class Reservation
attr_reader :booking_ref
attr_accessor :booking_ref, :number_of_rooms, :first_room_number, :check_in, :check_out, :total_cost, :room_blocks
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You probably should make all of these reader. Also, you don't need to double up-- booking_ref is in both reader and accessor and you should probably pick one

Comment thread lib/reservation.rb
DISCOUNTED_RATE = 160.00

def initialize(booking_ref:, number_of_rooms:, first_room_number:, check_in:, check_out:, total_cost:, room_blocks:)
@booking_ref = booking_ref
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is a booking_ref? Is there a requirement for this?

Comment thread lib/reservation.rb Outdated
@booking_ref = booking_ref

if (number_of_rooms <= 5)
@number_of_rooms = number_of_rooms
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There is no requirement that a reservation should have more than one room. Blocks should have different behavior: they are not a type of reservation

Comment thread lib/reservation.rb
raise ArgumentError, "A block can only have 5 rooms or less."
end # if

@first_room_number = first_room_number
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is a first_room_number? What does it represent?

Comment thread lib/reservation.rb Outdated
@total_cost = ((check_out - check_in) * number_of_rooms) * DISCOUNTED_RATE
end # if

@room_blocks = Array.new
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hm, I think that this isn't what the requirements were asking for...

Comment thread spec/block_room_spec.rb

it "creates an instance of BlockRoom" do
expect(@block_room).must_be_kind_of Hotel::BlockRoom
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Tests could be filled out a little more

Comment thread spec/front_desk_spec.rb
return Hotel::FrontDesk.new
end

describe "all arrays" do
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not the best name for this test! What if these values grow to not be arrays in the future? This is testing that the initial values are correct

Comment thread spec/front_desk_spec.rb
1,
Date.new(2019, 3, 20),
Date.new(2019, 3, 24),
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Probably would make sense to use keyword arguments here, since you defined them as such in Reservation

Comment thread spec/front_desk_spec.rb
expect(by_date).must_be_kind_of Array
expect(by_date.length).must_equal 1
expect(reservation_2.check_in).must_be :<, Date.new(2019, 4, 10)
expect(reservation_2.check_in).must_be :>, Date.new(2019, 4, 7)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You probably don't need to make assertions on reservation2 in this test, since you didn't alter it

Comment thread spec/front_desk_spec.rb
before do
@concierge = build_front_desk
end
it "will raise an ArgumentError if check_out date is before current date" do
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The logic for this test ends up living in the Reservation class, and you even test it there -- no need to double test it here in this file, unless this code was doing something different

Comment thread spec/front_desk_spec.rb
Date.new(2019, 10, 8),
Date.new(2019, 10, 12)
)
}.must_raise ArgumentError
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It isn't clear from this test why this is relevant to the test (it looks like a regular, valid reservation)-- maybe there are ways to use variable names and error detail testing to make this clear

Comment thread spec/front_desk_spec.rb
Date.new(2019, 7, 5)
)
}.must_raise ArgumentError
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would expect more edge cases than this!

Comment thread spec/front_desk_spec.rb
@concierge.add_block_reservations

expect(@concierge.block_reservations_only.length).must_equal 1
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What happens if you make two hotel blocks for the same date range?

Comment thread spec/front_desk_spec.rb
Date.new(2019, 7, 5),
Date.new(2019, 7, 6),
)
}.must_raise ArgumentError
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why should this raise an error? If this is a different case, then you should write a different test for it

Comment thread spec/reservation_spec.rb
check_out: Date.new(2019, 5, 24),
total_cost: @total_cost,
room_blocks: @room_blocks,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same as the comments that I had in your FrontDesk file... @total_cost will always be nil, no matter what, so you probably wouldn't want to say total_cost: @total_cost, but just total_cost: nil if that's what you're expecting

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