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

FarMar w/optional requirements I and II #45

Open
wants to merge 107 commits into
base: jlb/master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
8187624
create test for Market.all
jbuechs Oct 19, 2015
96aca23
complete market.all method
jbuechs Oct 19, 2015
905ce1b
update market initialize test
jbuechs Oct 19, 2015
7501c43
create init tests for product class
jbuechs Oct 20, 2015
0b1d39f
create product initialize method
jbuechs Oct 20, 2015
0257c58
create product all method
jbuechs Oct 20, 2015
26d719f
refactor to include farmar base class
jbuechs Oct 20, 2015
3b90a36
refactor init methods to use base class
jbuechs Oct 20, 2015
7d2ec0a
create sale tests
jbuechs Oct 20, 2015
c3c9aac
complete sale init and all methods
jbuechs Oct 20, 2015
26c7733
create vendor initialize test
jbuechs Oct 20, 2015
c3e1f21
create vendor initialize and convert_to_hash methods
jbuechs Oct 20, 2015
811c56f
create test for vendor all method
jbuechs Oct 20, 2015
d7c0791
create vendor all method
jbuechs Oct 20, 2015
19a397e
refactor self method to use filename constant
jbuechs Oct 20, 2015
e7c5234
create tests for market find method
jbuechs Oct 20, 2015
91d6330
complete beginning of market match method
jbuechs Oct 20, 2015
ae15ff7
create find method for market class
jbuechs Oct 20, 2015
45e2048
refactor find method to be in FarMar_Base class
jbuechs Oct 20, 2015
82b1f4f
delete redundant code in far_mar_base find method
jbuechs Oct 20, 2015
7693522
create find test for product class
jbuechs Oct 20, 2015
9259966
create find test for sale spec
jbuechs Oct 20, 2015
8f381d9
create test for vendor find method
jbuechs Oct 20, 2015
350c3b7
create test for vendors method of Market class
jbuechs Oct 21, 2015
6574074
bugfix syntax issues in vendor method test
jbuechs Oct 21, 2015
b2c706e
create vendor method
jbuechs Oct 21, 2015
70fd21b
create vendor self.by_market method
jbuechs Oct 21, 2015
cc59e46
refactor market vendors method
jbuechs Oct 21, 2015
ae1fac7
create tests for product.by_vendor
jbuechs Oct 21, 2015
b0d9433
create product.by_vendor method
jbuechs Oct 21, 2015
2d11ee2
create test for vendor.products
jbuechs Oct 21, 2015
352eb95
create vendor.products method
jbuechs Oct 21, 2015
a618188
create Sale.by_product(product_id)tests
jbuechs Oct 21, 2015
e8a36d1
create Sale.by_product method
jbuechs Oct 21, 2015
65f9e19
create test for product.sales
jbuechs Oct 21, 2015
011d60d
create product.sales method
jbuechs Oct 21, 2015
1776259
trying to create class variables
jbuechs Oct 21, 2015
6c60140
refactor base find and all methods
jbuechs Oct 21, 2015
fb55184
refactor market all_objects class variable
jbuechs Oct 21, 2015
cd3c06a
refactor classes to have class variable
jbuechs Oct 21, 2015
9ab5752
fix return in base self.all method
jbuechs Oct 21, 2015
8d925be
refactor vendor.by_market method
jbuechs Oct 21, 2015
0704ad6
refactor product.by_vendor method
jbuechs Oct 21, 2015
aac3714
refactor Sale.by_product method
jbuechs Oct 21, 2015
a2a9feb
create tests for vendor.sales
jbuechs Oct 21, 2015
a0540b0
create vendor.sales method
jbuechs Oct 21, 2015
dffc50f
create vendor.market test
jbuechs Oct 21, 2015
f078cfa
create vendor.market method
jbuechs Oct 21, 2015
488bae7
create test for Product.vendor
jbuechs Oct 21, 2015
b96f568
create Product.vendor method
jbuechs Oct 21, 2015
4adfe0c
create test for Vendor.revenue
jbuechs Oct 21, 2015
fb459c7
create Vendor.sales method
jbuechs Oct 21, 2015
e8c5280
create Product.number_of_sales test
jbuechs Oct 21, 2015
8c19748
create Product.number_of_sales method
jbuechs Oct 21, 2015
86b0f8b
create test for Sale.vendor
jbuechs Oct 21, 2015
1d1bd1f
create test for Sale.product
jbuechs Oct 21, 2015
e56c702
create Sale.vendor method
jbuechs Oct 21, 2015
0af63d6
create Sale.product method
jbuechs Oct 21, 2015
630e3e0
create test for Sale.between method
jbuechs Oct 21, 2015
8291147
create Sale.between method
jbuechs Oct 21, 2015
bea2ce4
add error checking for sale.between
jbuechs Oct 21, 2015
6258ab9
bugfix missing zip parameter in market class
jbuechs Oct 22, 2015
d501b90
refactor market_spec init test to iterate over hash
jbuechs Oct 22, 2015
41dc121
refactor product spec to check each attribute
jbuechs Oct 22, 2015
7914157
refactor sale_spec init tests
jbuechs Oct 22, 2015
9ae9e65
refactor vendor_spec init tests
jbuechs Oct 22, 2015
04a852d
create test for Market.products
jbuechs Oct 22, 2015
cbf491f
complete market.products method
jbuechs Oct 22, 2015
24315f5
create test for preferred vendor
jbuechs Oct 22, 2015
d31d8fb
create market.preferred_vendor method
jbuechs Oct 22, 2015
1ea8a80
create test for market.worst_vendor
jbuechs Oct 22, 2015
531b4e2
create market.worst_vendor method
jbuechs Oct 22, 2015
f81d6c3
create revenue instance variable in vendor class
jbuechs Oct 22, 2015
43df42b
refactor preferred and worst vendor methods
jbuechs Oct 22, 2015
b75b4d5
create test for Vendor.most_revenue
jbuechs Oct 22, 2015
da37dd8
create Vendor.most_revenue method
jbuechs Oct 22, 2015
d6ae240
create self.all for sale class to populate @@vendor_stats
jbuechs Oct 22, 2015
617e226
refactor Vendor.revenue method
jbuechs Oct 22, 2015
89c524f
refactor vendor.most_revenue
jbuechs Oct 22, 2015
f4bc0cc
refactor vendor.most_revenue method
jbuechs Oct 22, 2015
c31914f
create test for most_items method
jbuechs Oct 22, 2015
b6b9433
create vendor.most_items method
jbuechs Oct 22, 2015
09d17cc
refactor vendor most methods to use helper method
jbuechs Oct 22, 2015
56da2b2
create tests for vendor.day_revenue
jbuechs Oct 23, 2015
8786e42
create vendor.day_revenue method
jbuechs Oct 23, 2015
dc56cf2
create test for product.revenue
jbuechs Oct 23, 2015
1a30341
create revenue method for product class
jbuechs Oct 23, 2015
7eba918
refactor revenue method into vendor product base class
jbuechs Oct 23, 2015
05a6bdf
refactor most_x method to be in vend_prod_base class
jbuechs Oct 23, 2015
ad35326
create tests for vendor.revenue(date)
jbuechs Oct 23, 2015
d17b2b1
create self.revenue_on(date) in vendor class
jbuechs Oct 23, 2015
dc0b03d
create test for most_revenue(n) method
jbuechs Oct 23, 2015
177afd6
refactor VendorProductBase to be a module instead of class
jbuechs Oct 23, 2015
65eee10
bugfix in most_revenue test
jbuechs Oct 23, 2015
49825b1
refactor to use methods from VendorProductBase module
jbuechs Oct 23, 2015
207079c
refactor vendor class to use methods from VendorProductBase module
jbuechs Oct 23, 2015
6e68f8d
add comments to better understand all the refactoring
jbuechs Oct 23, 2015
79ad1aa
randomize running of rspec tests
jbuechs Oct 23, 2015
a8762fe
create beginnings of test for preferred and worst vendor
jbuechs Oct 23, 2015
39f5d0a
refactor market.prefered_vendor to have nil default date
jbuechs Oct 23, 2015
4355c9b
refactor worst_vendor method to have date as nil default
jbuechs Oct 23, 2015
d697e4a
create test for market.search method
jbuechs Oct 23, 2015
9de52ad
create FarMar::Market.search method
jbuechs Oct 23, 2015
1d9f047
create vendor.find_by_name(match) tests
jbuechs Oct 23, 2015
c234fdc
create vendor find_by_name
jbuechs Oct 23, 2015
5aa03f6
refactor find_by_name to be in far_mar_base file
jbuechs Oct 23, 2015
c02741f
minor edits of comments and code
jbuechs Oct 23, 2015
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
3 changes: 3 additions & 0 deletions lib/far_mar.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
require 'csv'
require 'time'
require 'pry'

# Order matters here so I might have to change it
require './lib/far_mar/far_mar_base'
require './lib/far_mar/vend_prod_base'
require './lib/far_mar/market'
require './lib/far_mar/vendor'
require './lib/far_mar/product'
Expand Down
43 changes: 43 additions & 0 deletions lib/far_mar/far_mar_base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module FarMar
class FarMar_Base
def initialize(init_hash)
# This block sets each key to an instance variable and assigns the value
init_hash.each do |k,v|
instance_variable_set("@#{k}", v) unless v.nil?
end
end

def self.all
if !self.class_variable_defined?(:@@all_objects)
csv_file = CSV.read(self::FILENAME)
# Create empty array which will hold all the objects
objects = []
csv_file.each do |row|
# Convert the array to a hash
csv_hash = self.convert_to_hash(row)
# Create an object from each row-hash in the csv file
temp = self.new(csv_hash)
# Push object to array of products
objects.push(temp)
end
self.class_variable_set(:@@all_objects, objects)
end
self.all_objects
end

def self.find(id)
self.all_objects.find { |obj| obj.id == id }
end

# returns a single instance whose attribute matches the parameter
def self.find_by_name(match)
return nil if match.class != String
result = FarMar::Vendor.all_objects.find do |vendor|
test_string = vendor.name.downcase
test_string.include?(match.downcase)
end
return result
end

end
end
90 changes: 89 additions & 1 deletion lib/far_mar/market.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,93 @@
module FarMar
class Market
class Market < FarMar_Base
attr_reader :id, :name, :address, :city, :county, :state, :zip
FILENAME = './support/markets.csv'

def initialize(market_hash)
super(market_hash)
end

def self.all_objects
@@all_objects ||= self.all
end

# Converts an array to a hash for passing to market instantiation
def self.convert_to_hash(market_array)
market_hash = {}
market_hash[:id] = market_array[0].to_i
market_hash[:name] = market_array[1]
market_hash[:address] = market_array[2]
market_hash[:city] = market_array[3]
market_hash[:county] = market_array[4]
market_hash[:state] = market_array[5]
market_hash[:zip] = market_array[6]
return market_hash
end

# Returns a collection of FarMar::Market instances where the market name
# or vendor name contain the search_term
def self.search(search_term)
return [] if search_term.class != String
search_term.downcase!
# find all markets that include the search term in the market name
market_match = FarMar::Market.all_objects.select do |market|
market_name = market.name.downcase
market_name.include?(search_term)
end
# find all markets that have the search term in the vendor name
vendor_match = FarMar::Vendor.all_objects.select do |vendor|
vendor_name = vendor.name.downcase
vendor_name.include?(search_term)
end
# This iterates through the vendors that include the search term
vendor_match.each do |vendor|
# and finds their associated market based on the market_id
market = FarMar::Market.find(vendor.market_id)
# then checks to see if the market is already in the market_match array
# and if not, it pushes it into the array
market_match.push(market) if !market_match.include?(market)
end
return market_match
end

# Returns a collection of FarMar::Vendor instances that are associated
# with the market by the market_id field
def vendors
return FarMar::Vendor.by_market(@id)
end

# returns a collection of FarMar::Product instances that are associated
# to the market through the FarMar::Vendor class
def products
products = []
v = vendors
v.each do |vendor|
products += vendor.products
end
return products
end

# returns the vendor with the highest revenue for the given date
# or returns the vendor with the highest revenue if no date is given
def preferred_vendor(date = nil)
return vendors.max_by { |vend| vend.revenue } if date.nil?
return nil if date.class != DateTime
m_vendors = vendors
rev = m_vendors.map { |vend| vend.day_revenue(date) }
max_index = rev.each_with_index.max[1]
return m_vendors[max_index]
end

# returns the vendor with the lowest revenue on the given date
# or returns the vendor with the lowest revenue if no date is given
def worst_vendor(date = nil)
return vendors.min_by { |vend| vend.revenue } if date.nil?
return nil if date.class != DateTime
m_vendors = vendors
rev = m_vendors.map { |vend| vend.day_revenue(date) }
min_index = rev.each_with_index.min[1]
return m_vendors[min_index]
end

end
end
54 changes: 53 additions & 1 deletion lib/far_mar/product.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
module FarMar
class Product
class Product < FarMar_Base
attr_reader :id, :name, :vendor_id
FILENAME = './support/products.csv'
REV_ATTR = :@@product_stats # the attribute accessed by the revenue method

# include adds methods to the instance of a class
# in this case, revenue is an instance method that is included
include VendorProductBase

def initialize(product_hash)
super(product_hash)
@revenue = revenue
end

def self.all_objects
@@all_objects ||= self.all
end

# Converts an array to a hash for passing to product instantiation
def self.convert_to_hash(product_array)
product_hash = {}
product_hash[:id] = product_array[0].to_i
product_hash[:name] = product_array[1]
product_hash[:vendor_id] = product_array[2].to_i
return product_hash
end

# returns all of the products with the given vendor_id
def self.by_vendor(vendor_id)
FarMar::Product.all_objects.find_all { |product| product.vendor_id == vendor_id }
end

# returns the top n products instances ranked by total revenue
def self.most_revenue(n)
most_x(n, "@revenue")
# FarMar::VendorProductBase.class_method(:most_x).bind(self).call(n, "@revenue")
end

# returns the FarMar::Vendor instance that is associated with this
# vendor using the vendor_id field
def vendor
return FarMar::Vendor.find(@vendor_id)
end

# returns a collection of FarMar::Sale instances that are associated using
# the product_id field
def sales
return FarMar::Sale.by_product(@id)
end

# returns the number of times the product has been sold
def number_of_sales
return sales.length
end
end
end
96 changes: 95 additions & 1 deletion lib/far_mar/sale.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,99 @@
module FarMar
class Sale
class Sale < FarMar_Base
attr_reader :id, :amount, :purchase_time, :vendor_id, :product_id
FILENAME = './support/sales.csv'

def initialize(sale_hash)
super(sale_hash)
end

def self.all_objects
@@all_objects ||= self.all[0]
end

def self.vendor_stats
@@vendor_stats ||= self.all[1]
end

def self.product_stats
@@product_stats ||= self.all[2]
end

def self.all
if !self.class_variable_defined?(:@@all_objects) ||!self.class_variable_defined?(:@@vendor_stats)
csv_file = CSV.read(FILENAME)
# Create empty array which will hold all the objects
objects = []
vend_stats = {}
prod_stats = {}
csv_file.each do |row|
# Convert the array to a hash
sale_hash = convert_to_hash(row)
# Create an object from each row-hash in the csv file
temp = self.new(sale_hash)
# Push object to array of products
objects.push(temp)
# Populate the vend_stats array
if vend_stats[sale_hash[:vendor_id]].nil? # if there is no revenue yet
vend_stats[sale_hash[:vendor_id]] = {}
vend_stats[sale_hash[:vendor_id]][:revenue] = sale_hash[:amount] # store the first revenue
vend_stats[sale_hash[:vendor_id]][:num_sales] = 1 # and tally 1 for number of sales
else
vend_stats[sale_hash[:vendor_id]][:revenue] += sale_hash[:amount] # add the amount to the revenue
vend_stats[sale_hash[:vendor_id]][:num_sales] += 1 # and add 1 to sale tally
end
# Populate product_stats array
if prod_stats[sale_hash[:product_id]].nil? # if there is no product revenue yet
prod_stats[sale_hash[:product_id]] = {}
prod_stats[sale_hash[:product_id]][:revenue] = sale_hash[:amount] # stores the first revenue
else
prod_stats[sale_hash[:product_id]][:revenue] += sale_hash[:amount] # adds the amount to the revenue
end
end
return self.class_variable_set(:@@all_objects, objects), self.class_variable_set(:@@vendor_stats, vend_stats), self.class_variable_set(:@@product_stats, prod_stats)

end
self.all_objects
end

def self.convert_to_hash(sale_array)
sale_hash = {}
sale_hash[:id] = sale_array[0].to_i
sale_hash[:amount] = sale_array[1].to_i
sale_hash[:purchase_time] = DateTime.parse(sale_array[2])
sale_hash[:vendor_id] = sale_array[3].to_i
sale_hash[:product_id] = sale_array[4].to_i
return sale_hash
end

# returns all of the sales with the given product id
def self.by_product(product_id)
return FarMar::Sale.all_objects.find_all { |sale| sale.product_id == product_id }
end

# returns all of the sales with the given vendor id
def self.by_vendor(vendor_id)
return FarMar::Sale.all_objects.find_all { |sale| sale.vendor_id == vendor_id }
end

# returns a collection of FarMar::Sale objects where the purchase time
# is between the two times given as arguments
def self.between(beginning_time, end_time)
return [] if
beginning_time.class != DateTime ||
end_time.class != DateTime ||
end_time <= beginning_time
return FarMar::Sale.all_objects.find_all { |sale_obj| sale_obj.purchase_time > beginning_time && sale_obj.purchase_time < end_time }
end

# returns the Vendor that is associated with the sale
def vendor
return FarMar::Vendor.find(@vendor_id)
end

# returns the Product that is associated with the sale
def product
return FarMar::Product.find(@product_id)
end
end
end
34 changes: 34 additions & 0 deletions lib/far_mar/vend_prod_base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module FarMar
module VendorProductBase
# info from http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/
def self.included(base)
# extend is for adding class methods
base.extend(ClassMethods)
end

module ClassMethods
# these are class methods for the VendorProductBase module
# written this way so that "self" refers to the class that is calling it
# self is either FarMar::Vendor or FarMar::Product
def most_x(n, attribute)
return [] if
n.class != Fixnum ||
n < 0 ||
n > self.all_objects.length
backwards = self.all_objects.sort_by { |obj| obj.instance_variable_get(attribute) }
sorted = backwards.reverse
return sorted[0, n]
end
end

def revenue
return @revenue if [email protected]?
results = FarMar::Sale.class_variable_get(self.class::REV_ATTR)
if results[@id].nil?
@revenue = 0
else
@revenue = results[@id][:revenue]
end
end
end
end
Loading