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

Karin's FarMar #48

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
440b5c8
setting up spec and class files
wordkarin Sep 6, 2016
e959587
adding gitignore file
wordkarin Sep 6, 2016
48305a1
added one spec test for market, it passes
wordkarin Sep 6, 2016
8c94bd1
updated spec and class for product
wordkarin Sep 6, 2016
dccd6be
updated sale_spec and sale class
wordkarin Sep 6, 2016
60bda62
updated vendor spec/class
wordkarin Sep 6, 2016
9e4fbb2
updated specs with initialize tests, pass
wordkarin Sep 6, 2016
750fc95
got explanation for what far_mar is doing
wordkarin Sep 6, 2016
52b64ff
fixed initialize for sale
wordkarin Sep 6, 2016
2f806ab
added additional initializtion tests
wordkarin Sep 6, 2016
5847eb7
added specs for self.all and self.find(id), they pass
wordkarin Sep 6, 2016
d10d807
specs added for vendor .all method, pass
wordkarin Sep 6, 2016
ef2fbf0
added specs for vendor .find(id), pass
wordkarin Sep 6, 2016
a9fbb00
product .self and .find methods written/tested
wordkarin Sep 6, 2016
42754dc
added self.all spec, it's currently broken
wordkarin Sep 7, 2016
8db8140
fixed DateTime conversion, tests pass
wordkarin Sep 7, 2016
f26f5e4
Wrote #vendors method for Market
wordkarin Sep 7, 2016
c98ccea
added #market method to vendor, tests pass
wordkarin Sep 7, 2016
a265355
Moved the Vendor.by_market code out of Market's #vendors method
wordkarin Sep 7, 2016
2e96f34
added comments for rest of vendor methods
wordkarin Sep 8, 2016
2197d5a
adding notes for additional methods
wordkarin Sep 8, 2016
acdaacf
added find(id) method to sale, passes first test
wordkarin Sep 8, 2016
43cc4dc
fixed other sale tests for find(id)
wordkarin Sep 8, 2016
28b19ef
updated comments in sale class
wordkarin Sep 8, 2016
6be2376
updated sale's vendor method test
wordkarin Sep 8, 2016
8f1b767
added Product.by_vendor(vendor_id) method, tests pass
wordkarin Sep 8, 2016
411e538
wrote tests for vendor's products method
wordkarin Sep 8, 2016
68116ba
added Vendor's product method, tests pass
wordkarin Sep 8, 2016
efa5d99
Added vendor method to Sale, tests pass
wordkarin Sep 8, 2016
aeebee3
added product method to sale, tests pass
wordkarin Sep 8, 2016
c2d2c62
Added product sales method, tests pass
wordkarin Sep 8, 2016
2c0b783
added tests for vendor sales method
wordkarin Sep 8, 2016
7bae167
wrote vendor sales method, accounts for if there are no sales for a p…
wordkarin Sep 8, 2016
8807596
added number_of_sales method, tests pass
wordkarin Sep 8, 2016
addd1c9
added vendor revenue method, tests pass
wordkarin Sep 8, 2016
0f031b9
fixed some of the comments
wordkarin Sep 8, 2016
030c96e
notes about filter vs group_by
wordkarin Sep 9, 2016
ca2484a
added tests for Sale.between(b,e) method
wordkarin Sep 9, 2016
9a37fa5
wrote Sale.between(b,e) method, tests pass
wordkarin Sep 9, 2016
1bd8d8d
primary requirements complete
wordkarin Sep 9, 2016
17908d2
prefered vendor method works, slowly.
wordkarin Sep 9, 2016
ba35b1c
updated notes around products without sales
wordkarin Sep 9, 2016
d71c971
switched product.sales from group_by to select
wordkarin Sep 9, 2016
c4124d3
oops, now fixed comments around vendor sales method
wordkarin Sep 9, 2016
5b4f709
Updating Sale with a class variable for .all method
wordkarin Sep 13, 2016
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage/
11 changes: 11 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# I have also just copied the contents of the Rakefile that was included in the in-class TDD demo.
# To run the rake tests, just be inside the FarMar directory in your terminal and type 'rake'.

require 'rake/testtask'

Rake::TestTask.new do |t|
t.test_files = FileList['specs/*_spec.rb']
#this is the set of files that will be tested.
end

task default: :test
11 changes: 11 additions & 0 deletions far_mar.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# gems your project needs
require 'csv'

# our namespace module
module FarMar; end

# all of our data classes that live in the module
require_relative './lib/farmar_market'
require_relative './lib/farmar_product'
require_relative './lib/farmar_sale'
require_relative './lib/farmar_vendor'
78 changes: 78 additions & 0 deletions lib/farmar_market.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'csv'

module FarMar
class Market
attr_reader :id, :name, :address
def initialize (id, name, address, city, county, state, zip)
# ID - (Fixnum) a unique identifier for that market
@id = id
# Name - (String) the name of the market (not guaranteed unique)
@name = name
# Address - (String) street address of the market
@address = address
# City - (String) city in which the market is located
# County - (String) county in which the market is located
# State - (String) state in which the market is located
# Zip - (String) zipcode in which the market is located)
end

def self.all
# self.all: returns a collection of instances, representing all of the objects described in the CSV
markets = {}

CSV.read("support/markets.csv").each do |line|
# Is there a way to do this with an enumerable instead of an each?
# id = line[0].to_i
# name = line[1]
# address = line[2]
# city = line[3]
# county = line[4]
# state = line[5]
# zip = line[6].to_i

id, name, address, city, county, state, zip = line # parallel assignment!
id = id.to_i # need id to be a fixnum
zip = zip.to_i # want zip to be a fixnum also (I think)

markets[id] = self.new(id, name, address, city, county, state, zip)
end

return markets
end

def self.find(id)
# self.find(id): returns an instance of the object where the value of the id field in the CSV matches the passed parameter.
all_markets = self.all
return all_markets[id]
end

def vendors
Vendor.by_market(@id)
# Call Vendor.all (returns a hash of vendors)
# The Vaules of the Vendor.all hash is an array of Vendors, so want to group those on their market_id.
# Then, want only the vendors that correspond to the market instance's id.
end

def prefered_vendor
#prefered_vendor: returns the vendor with the highest revenue
# I'm going to start with an array of all vendors for the MARKET. (market.vendors), then I want to calculate the revenue for each vendor, and store it with the corresponding vendor (hash, where revenue is the key, value is an array of vendors with that revenue, in case there are more than one). then, call .max on the keys of the hash, get the key, call the value. Or I can just use max_by.
vendors.max_by { |vendor| vendor.revenue }

end
end
end


# This is what I wrote for the accounts self.all to read in the csv file.
# def self.all
# accounts = {}
#
# CSV.read("support/accounts.csv").each do |line|
# account_id = line[0].to_i
# balance = line[1].to_i
# open_date = line[2]
# accounts[account_id] = self.new(account_id, open_date, balance)
# end
#
# return accounts
# end
63 changes: 63 additions & 0 deletions lib/farmar_product.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require 'csv'

module FarMar
class Product
attr_reader :product_id, :product_name, :vendor_id
def initialize(product_id, product_name, vendor_id)
# ID - (Fixnum) uniquely identifies the product
@product_id = product_id
# Name - (String) the name of the product (not guaranteed unique)
@product_name = product_name
# Vendor_id - (Fixnum) a reference to which vendor sells this product
@vendor_id = vendor_id
end

def self.all
# self.all: returns a collection of instances, representing all of the objects described in the CSV
products = {}

CSV.read("support/products.csv").each do |line|
product_id, product_name, vendor_id = line # parallel assignment!
product_id = product_id.to_i # need product_id to be a fixnum
vendor_id = vendor_id.to_i #want vendor_id to be a fixnum

products[product_id] = self.new(product_id, product_name, vendor_id)
end

return products
end

def self.find(id)
# self.find(id): returns an instance of the object where the value of the id field in the CSV matches the passed parameter.
specific_product = Product.all
return specific_product[id]
end

def vendor
#vendor: returns the FarMar::Vendor instance that is associated with this vendor using the FarMar::Product vendor_id field - this will work LIKE the vendor.market method.
Vendor.find(@vendor_id)
end

def self.by_vendor(vendor_id)
# self.by_vendor(vendor_id): returns all of the products with the given vendor_id (will call this in the Vendor #products method. )
all.values.select { |product| product.vendor_id == vendor_id }
#I don't like that these things are called the same thing -- I have an instance variable @vendor_id for a product instance, and the argument vendor_id that is getting passed in. Seems to be working though.
#TODO: rather than using group_by and getting all the product groups by vendor_id, and then throwing away all the groups except the one I care about, research using "filter".
end

def sales
#sales: returns an array of FarMar::Sale instances that are associated using the FarMar::Sale product_id field.
Sale.all.values.select {|sale| sale.product_id == @product_id}
# Sale.all.values.group_by {|sale| sale.product_id}[@product_id]
#NOTE: It possible that a given product has NO sales.
end

def number_of_sales
#number_of_sales: returns the number of times this product has been sold.
sales.length
end
end
end


#number_of_sales: returns the number of times this product has been sold.
65 changes: 65 additions & 0 deletions lib/farmar_sale.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
require 'csv'
# require 'date'

module FarMar
class Sale
@@all_sales = nil
attr_reader :sale_id, :amount, :vendor_id, :product_id, :purchase_time
def initialize(sale_id, amount, purchase_time, vendor_id, product_id)
# sale_id, amount, purchase_time, vendor_id, product_id)
# ID - (Fixnum) uniquely identifies the sale
@sale_id = sale_id
# Amount - (Fixnum) the amount of the transaction, in cents (i.e., 150 would be $1.50)
@amount = amount
# Purchase_time - (Datetime) when the sale was completed
@purchase_time = DateTime.parse(purchase_time) # purchase_time in csv is the string representation of a datetime, not the comma delimited input that Datetime is expecting. https://ruby-doc.org/stdlib-2.3.1/libdoc/date/rdoc/DateTime.html#method-c-parse
# Vendor_id - (Fixnum) a reference to which vendor completed the sale
@vendor_id = vendor_id
# Product_id - (Fixnum) a reference to which product was sold
@product_id = product_id
end

def self.all
# self.all: returns a collection of instances, representing all of the objects described in the CSV
if @@all_sales == nil

@@all_sales = {}

CSV.read("support/sales.csv").each do |line|
sale_id, amount, purchase_time, vendor_id, product_id = line # parallel assignment!
sale_id = sale_id.to_i # need sale_id to be a fixnum
amount = amount.to_i # want amount to be a fixnum also
vendor_id = vendor_id.to_i # want vendor_id to be a fixnum
product_id = product_id.to_i # want product_id also to be a fixnum

@@all_sales[sale_id] = self.new(sale_id, amount, purchase_time, vendor_id, product_id)
end
end

return @@all_sales
end

def self.find(id)
# self.find(id): returns an instance of the object where the value of the id field in the CSV matches the passed parameter.
#this is going to call self.all, and then find the one with key of id
all[id]
end

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

def product
#product: returns the FarMar::Product instance that is associated with this sale using the FarMar::Sale product_id field
Product.find(@product_id)
end

def self.between(beginning_time, end_time)
between_sales = Sale.all.select do |key, value|
value.purchase_time >= beginning_time && value.purchase_time <= end_time
end
between_sales
end
end
end
94 changes: 94 additions & 0 deletions lib/farmar_vendor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
require 'csv'

module FarMar
class Vendor
attr_reader :id, :name, :market_id, :num_employees
def initialize(id, name, num_employees, market_id)
# ID - (Fixnum) uniquely identifies the vendor
@id = id
# Name - (String) the name of the vendor (not guaranteed unique)
@name = name
# No. of Employees - (Fixnum) How many employees the vendor has at the market
@num_employees = num_employees
# Market_id - (Fixnum) a reference to which market the vendor attends
@market_id = market_id
end

def self.all
# self.all: returns a collection of instances, representing all of the objects described in the CSV
vendors = {}

CSV.read("support/vendors.csv").each do |line|
id, name, num_employees, market_id = line # parallel assignment!
id = id.to_i # need id to be a fixnum
num_employees = num_employees.to_i # want num_employees to be a fixnum also
market_id = market_id.to_i #want market_id to be a fixnum

vendors[id] = self.new(id, name, num_employees, market_id)
end

return vendors
end

def self.find(id)
# self.find(id): returns an instance of the object where the value of the id field in the CSV matches the passed parameter.
all_vendors = self.all
all_vendors[id]
end

def market
#market: returns the FarMar::Market instance that is associated with this vendor using the FarMar::Vendor market_id field
# Return the market object that corresponds to the instance's market_id.
Market.find(@market_id)
end

def self.by_market(market_id)
# self.by_market(market_id): returns all of the vendors with the given market_id
Vendor.all.values.select { |vendor| vendor.market_id == market_id }

#I don't like that these things are called the same thing -- I have an instance variable @market_id for a vendor instance, and the argument market_id that is getting passed in. Seems to be working though.
end

def products
#products: returns an array of FarMar::Product instances that are associated by the FarMar::Product vendor_id field. Seems to be related to the Product.by_vendor(id), which returns all the products with a given vendor_id.
Product.by_vendor(@id)
end

def sales
#sales: returns a collection of FarMar::Sale instances that are associated by the vendor_id field.
# for this vendor object, I should get the list of products associated with it, then call product.sales for each of those products, which should return a collection of sales (probably as a hash, keyed off of product_id).
sales_hash = {}

products.each do |product| #for each product do the following.
# it is possible for there to be no sales for a given product
# unless product.sales == nil
unless product.sales == []
#product.sales will return an empty array for products that have no sales.
sales_hash[product] = product.sales
end
end

return sales_hash
end

def revenue
#revenue: returns the the sum of all of the vendor's sales (in cents)
#probably uses the #sales method, grabs the amount associated with each sale, and then reduces (:+) them to a sum?
#sales returns a hash with key value pairs of product: [array of sales], so I'll want to iterate through each array of sales, grab the sale.amount, make a collection of those, and reduce them to the sum. Then for each product, I'll have a a total sale amount. (maybe use a map here), and I can then reduce again to get the total revenue.
revenue_by_product = sales.map do |k, v|
#v is an array of sales
#want to get an array of sale.amounts for it.
amounts = []
v.each do |sale|
amounts << sale.amount
end

# taking the array of sale.amounts, I'm going to reduce to get revenue for this product. The result should be an array of revenues per product. (number of amounts in this array should equal the same number of products for the vendor where there have been a sale.)
# at some point in the future, I might want to keep the product as the key, but for right now I don't think I care.
amounts.reduce(:+)
end

revenue_by_product.reduce(:+)
end
end
end
Loading