Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs = ["lib"]
t.warning = true
t.test_files = FileList['specs/*_spec.rb']
end

task default: :test
64 changes: 64 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
Prompts

1. What classes does each implementation include? Are the lists the same?

Implementation A - CartEntry, ShoppingCart, Order

Implementation B - CartEntry, ShoppingCart, Order

Yes, they look to be the same, the differences look to be in the methods.

2. Write down a sentence to describe each class.
How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper.

Implementation A - To calculate the price of the Order, the Order class has to access the instance variables of CartEntry and ShoppingCart in order to calculate the total_price.

Implementation B - In this case it is the ShoppingCart class which calls the price method of CartEntry in order to calculate the price of all instances (@entries) of CartEntry. From there the Order class calls the price method from the ShoppingCart class to calculate the total of everything that is located in @cart.

All in all Implementation B is much more sensical, especially seeing them side-by-side.

4. What data does each class store? How (if at all) does this differ between the two implementations?

Each class stores the same data in both implementations.

CartEntry stores data for quantity and unit price of each instance of CartEntry in the ShoppingCart class.

ShoppingCart contains all of these instances in an array.

Order contains a constant variable. This is set equal to the sales tax, as well as, an instance of ShoppingCart.

5. What methods does each class have? How (if at all) does this differ between the two implementations?

The methods between the two implementations do differ, as such;

Implementation A - The classes CartEntry and ShoppingCart have only initialize methods. There is one main method with all of the logic placed in the Order class. This method essentially does the order pricing calculations and does so by directly accessing/using the instance variables located in ShoppingCart and CartEntry.

Implementation B - The classes have changed here with CartEntry and ShoppingCart now containing their own price methods with logic that allows for them to calculate the total price of the Order class.

CartEntry's calculation method calculates the cost of an instance of CartEntry. ShoppingCart's method calculates the total cost of all instances of CartEntry via @entries, which it does by calling the price method of CartEntry from within the class of ShoppingCart. The addition of the Order class having a total_price method that adds in tax to the sum by calling on the price method in ShoppingCart.

6. Consider the Order#total_price method. In each implementation:

Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order?

Implementation A - Logic is in the Order class, with the total_price method directly reading the instance variables of the ShoppingCart and CartEntry which then provides a calculation via the total_price method.

Implementation B - There is a change in logic, which is now in the 'lower level classes'. In order to calculate total_price the 'higher level classes' call on the methods of the instances provided in the 'lower level' instead of calling on them directly as in Implementation A.

7. Does total_price directly manipulate the instance variables of other classes?

Implementation A - There is a small degree of manipulation with the entries through the loop.

Implementation B - No, not in this case that I could tell.

8. If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?

Implementation B - It is much easier to change the logic of the price method and provide/add a 'discount' depending on what is considered bulk. Thus defining what is considered 'bulk' and worthy of a discounted rate, then setting up that discount in the price method as a conditional could be one way to potentially go about this.

9. Which implementation better adheres to the single responsibility principle?

Implementation B - This because the classes in B have both behaviour and state. Adding that the methods of higher level classes don't rely directly on the lower level classes.

10. Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?

Implementation B - This because the classes components are in my opinion what I would call more 'self-reliant' and work more cohesively together due to that.
60 changes: 60 additions & 0 deletions lib/hotel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# All buisiness logic here (changed mind from reservations because this makes most sense).

# I need for this to access all of the rooms in the room class.

# I need for this to access all of the reservations, the reservations class holds my dates for the reservations.

# I need for this to provide a total charge amount for the days reserved.

# Somehow I need this to provide reservation list that is DATE specific. This will be tricky (IMO).

require_relative 'rooms'
require_relative 'reservations'

module HotelHedwig
class Reservations
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're redoing this class again?

attr_reader :rooms, :check_in, :check_out, :total_charges
def initialize(rooms, check_in, check_out, total_charges)
@rooms = rooms
@check_in = check_in
@check_out = check_out
@total_charges = total_charges
end

# Start pseudocode
# Remember to not duplicate methods!

def all_rooms
@rooms = []
end

def reserve_room(room, check_in, check_out)


end

def date_reservations

end

# Calculating costs take 3, not sure how to best calculate this or if it belongs here. The idea is using the base amount aka room_cost (200) multiplied by the number of days customer stays. Check out day minus check in day provides that number. I hope. This should also allow for a one day stay ex. 200 * (day 2 - day 1) = 200 * 1 = 200.

def total_charges
@room_rate = room_rate * (@check_out - @check_in).to_i
end
end
end


# User Stories Wave 1 (methods);

# As an administrator, I can access the list of all of the rooms in the hotel
# As an administrator, I can reserve a room for a given date range
# As an administrator, I can access the list of reservations for a specific date
# As an administrator, I can get the total cost for a given reservation

# Constraints

# The hotel has 20 rooms, and they are numbered 1 through 20
# Every room is identical, and a room always costs $200/night
# The last day of a reservation is the checkout day, so the guest should not be charged for that night
30 changes: 30 additions & 0 deletions lib/reservations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Logic for reservations here, aka reservation dates.
# I need this to require the date gem.
# This must initialize check in and check out dates
# This must also take those dates and use a method to calculate charges.
# I need to make sure that I can access this information in the hotel class which is going to hold all of the biz logic.

require 'date'
require 'rooms'

module HotelHedwig
class Reservations

attr_reader :check_in, :check_out

def initialize(check_in, check_out)
@check_in = check_in
@check_out = check_out

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 looks like this initialize method isn't closed with an end properly.

# Raise an argument error IF the check-in date is after the check-out date! Method?

# Why is invalid_date raising a warning???

def invalid_date
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good method to have, just need to use it!

if @check_in < @check_out
raise ArgumentError.new("Invalid date selection, please check and change your check-in and check-out dates.")
end
end
end
end
end
28 changes: 28 additions & 0 deletions lib/rooms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Room logic. SIMPLE
# I need this to provide me with 20 numbered rooms starting at the number 1 and ending at the number 20.
# This also needs to (I believe) hold the room cost. Each room has a $200 charge per night.

module HotelHedwig
class 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.

I would probably name this class Room instead of Rooms. Since it describes a single room.


attr_reader :room_num, :room_rate

# Initialize variables to access the room number AND the charge per room. I believe this will make it easier to calculate in the end.

def initialize(room_num)
@room_num = room_num
@room_rate = 200
end

# Using a self.all method to work out the room numbering system.

def self.all
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

A good start on this, but you'd need to initialize number (probably to 0) and having return rooms at the end of the method.

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 is a good idea, down the road to have a .all method like this, but also notice that this method generates an all new list each time.

rooms = []
room_num = 0
20.times do
number += 1
rooms << self.new(room_num)
end
end
end
end
38 changes: 38 additions & 0 deletions specs/hotel_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require_relative 'spec_helper'

describe "Hotel" do
before do
@check_in = Date.new(2017,9,11)
@check_out = Date.new(2017,9,13)
@reservation_dates = HotelHedwig::Reservations.new(@check_in, @check_out)
end


# Test pseudocode

describe "#initialize" do
it "" do
end
end

describe "all_rooms" do
it "Must be an array of rooms" do
end
end

describe "reserve_room" do
it "Must allow reservation by date range" do
end
end

describe "date_reservations" do
it "Must be able to access reservation list by specific date" do
end
end

describe "total_charges" do
it "Must have a charge of $200 per night" do
@charges.must_equal
end
end
end
21 changes: 21 additions & 0 deletions specs/reservations_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_relative 'spec_helper'

describe "Reservations" do
before do
@check_in = Date.new(2017,9,11)
@check_out = Date.new(2017,9,13)
@reservation_dates = HotelHedwig::Reservations.new(@check_in, @check_out)
end

it "Must be instance of Reservations" do
@reservation_dates.must_be_instance_of HotelHedwig::Reservations
end

describe "invalid_date" do
it "Must raise argument error if check-in date is after check out date" do
proc { HotelHedwig::Reservations.new(@check_in < @check_out) }.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.

You're passing initialize a boolean (true/false) instead of two dates.

end
end
end

# More testing needed. Big time.
28 changes: 28 additions & 0 deletions specs/rooms_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require_relative 'spec_helper'

describe "Rooms" do
describe "#initialize" do
before do
@room_1 = HotelHedwig::Rooms.new(1)
end

# Basic needs tests to access room numbers and the cost.
# Can I do anything else?

it "Can access a room number." do
@room_1.room_num.must_equal 1
end

it "Can access the cost of a room per night." do
@room_1.room_rate.must_equal 200
end

it "Must respond to room_num" do
@room_1.must_respond_to :room_num
end

it "Must be instance of HotelHedwig module and Rooms class" do
@room_1.must_be_instance_of HotelHedwig::Rooms
end
end
end
8 changes: 8 additions & 0 deletions specs/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'simplecov'
SimpleCov.start
require 'minitest/autorun'
require 'minitest/reporters'
require 'minitest/skip_dsl'
require_relative '../lib/rooms'
require_relative '../lib/hotel'
require_relative '../lib/reservations'