Skip to content

Instantly share code, notes, and snippets.

@sranso
Last active May 3, 2016 05:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sranso/9bb155249a2c3b831dfd4e27d37dd495 to your computer and use it in GitHub Desktop.
Save sranso/9bb155249a2c3b831dfd4e27d37dd495 to your computer and use it in GitHub Desktop.
# This gist contains (1) working code and (2) tests for that code. I divided them
# by a line (=====), and added notes on how to run the code.
# Code generates a random cart of items and a random set of coupons.
# Implements a method checkout to calculate total cost of a cart of items and apply discounts and coupons as necessary.
ITEMS = [ {"AVOCADO" => {:price => 3.00,:clearance => true}},
{"KALE" => {:price => 3.00,:clearance => false}},
{"BLACK_BEANS" => {:price => 2.50,:clearance => false}},
{"ALMONDS" => {:price => 9.00,:clearance => false}},
{"TEMPEH" => {:price => 3.00,:clearance => true}},
{"CHEESE" => {:price => 6.50,:clearance => false}},
{"BEER" => {:price => 13.00,:clearance => false}},
{"PEANUTBUTTER" => {:price => 3.00,:clearance => true}},
{"BEETS" => {:price => 2.50,:clearance => false}}]
COUPS = [ {:item=>"AVOCADO", :num=>2, :cost=>5.00},
{:item=>"BEER", :num=>2, :cost=>20.00},
{:item=>"CHEESE", :num=>3, :cost=>15.00}]
#randomly generates a cart of 20 items
def generate_cart
cart = []
rand(20).times do
cart.push(ITEMS.sample)
end
cart
end
#randomly generates set of 4 coupons
def generate_coups
coups = []
rand(4).times do
coups.push(COUPS.sample)
end
coups
end
#counts number of items in cart
def count(cart)
cart.size
end
#counts for multiple items in cart
def multiples(cart)
cart.each do |item|
item.each do |name, attributes|
attributes[:count] = cart.select{|each_item| each_item == item}.size
end
end
cart.uniq
end
#check for coupons and apply the discount if the proper number of items is present, returns new total cost
def apply_coupons1(cart, coupons)
cost = 0
cart.each do |item|
item.each do |name, attributes|
coupons.each do |coupon|
if coupon[:item] == name && attributes[:count] >= coupon[:num] #if name of coupon item equals name of item in cart && number of items needed for coupon >= number of items in cart count
cost += coupon[:cost] #add the cost from the discount item to cost
end
end
end
end
cost
end
#remove coupon-ed items from the cart, returns new cart
def apply_coupons2(cart, coupons)
cart.each do |item|
item.each do |name, attributes|
coupons.each do |coupon|
if coupon[:item] == name && attributes[:count] >= coupon[:num] #if name of coupon item equals name of item in cart && number of items needed for coupon >= number of items in cart count
attributes[:count] = attributes[:count] - coupon[:num] #change number of items in cart
end
end
end
end
cart
end
#calculates cost of multiple items. need to pass multiples in.
def cost_of_multiples(cart)
cart.each do |item|
item.each do |name, attributes|
attributes[:price] = attributes[:price]*attributes[:count]
end
end
cart
end
#if any of the items are on clearance add a 20% discount
def apply_clearance(cart)
cart.each do |item|
item.each do |name, attributes|
if attributes[:clearance] == true
attributes[:price] = (attributes[:price]*0.8).round(2)
end
end
end
cart
end
#if none of the items purchased have a unit price greater than 5$ give the customer a 10$ discount off the whole cart
def ten_discount(cart, total_cost)
over_five = false
cart.each do |item|
item.each do |name, attributes|
if attributes[:price] > 5.0
over_five = true
end
end
end
if over_five == false && total_cost >= 10
return total_cost - 10
end
total_cost
end
#calculates the total cost of the cart, after calculating cost of multiples
def checkout(cart)
total_cost = []
cart.each do |item|
item.each do |name, attributes|
total_cost << attributes[:price]
end
end
total_cost.reduce(:+)
end
# ====================================================================================================================
# Tests
# To run, create a file called green-grocer-spec.rb, and in the command line run `rspec green-grocer-spec.rb`.
# If you don't have rspec installed on your machine, you can do so here https://rubygems.org/gems/rspec/versions/3.4.0
require "rspec" # do i need this
require "./green-grocer"
describe "#count" do
it "should count the total number of items in the cart" do
expect(count([{"AVOCADO" => {:price => 3.00,:clearance => true}},{"AVOCADO" => {:price => 3.00,:clearance => true}}])).to eq(2)
end
end
describe "#multiples" do
it "should tell you the number of multiple items in the cart" do
expect(multiples([{"KALE"=>{:price=>3.0, :clearance=>false, :count=>2}}, {"KALE"=>{:price=>3.0, :clearance=>false, :count=>2}}])).to eq([{"KALE"=>{:price=>3.0, :clearance=>false, :count=>2}}])
end
end
describe "#cost_of_multiples" do
it "should calculate the cost of all items in the cart" do
expect(cost_of_multiples([{"KALE"=>{:price=>3.0, :clearance=>false, :count=>2}}])).to eq([{"KALE"=>{:price=>6.0, :clearance=>false, :count=>2}}])
end
end
describe "#checkout" do
it "should calculate the total cost of the cart" do
expect(checkout([{"AVOCADO"=>{:price=>3.0, :clearance=>true, :count=>1}},
{"BLACK_BEANS"=>{:price=>5.0, :clearance=>false, :count=>2}},
{"BEER"=>{:price=>13.0, :clearance=>false, :count=>1}},
{"BEETS"=>{:price=>2.5, :clearance=>false, :count=>1}}])).to eq(23.5)
end
end
describe "#apply_coupons1" do
it "should add cost of coupons to an empty cost" do
expect(apply_coupons1([{"AVOCADO"=>{:price=>6.0, :clearance=>true, :count=>2}},
{"TEMPEH"=>{:price=>6.0, :clearance=>true, :count=>2}},
{"CHEESE"=>{:price=>26.0, :clearance=>false, :count=>4}}],[{:item=>"AVOCADO", :num=>2, :cost=>5.0}])).to eq(5)
end
end
describe "#apply_coupons2" do
it "should remove coupon-ed items from the cart, returns new cart" do
expect(apply_coupons2([{"AVOCADO"=>{:price=>3.0, :clearance=>true, :count=>3}},
{"TEMPEH"=>{:price=>6.0, :clearance=>true, :count=>2}},
{"CHEESE"=>{:price=>26.0, :clearance=>false, :count=>4}}],[{:item=>"AVOCADO", :num=>2, :cost=>5.0}])).to eq([{"AVOCADO"=>{:price=>3.0, :clearance=>true, :count=>1}},
{"TEMPEH"=>{:price=>6.0, :clearance=>true, :count=>2}},
{"CHEESE"=>{:price=>26.0, :clearance=>false, :count=>4}}])
end
end
describe "#triple_discount" do
it "should triple the discount if the customer has 2 of the same coupon" do
old_cart = [{"AVOCADO" => {:price => 3.00,:clearance => true}},
{"CHEESE" => {:price => 6.50,:clearance => false}}]
new_cart = [{"AVOCADO" => {:price => 3.00,:clearance => true}},
{"CHEESE" => {:price => 6.50,:clearance => false}}]
coupons = [ {:item=>"AVOCADO", :num=>2, :cost=>5.00},
{:item=>"CHEESE", :num=>3, :cost=>15.00},
{:item=>"CHEESE", :num=>3, :cost=>15.00}]
expect(triple_discount(old_cart).to.be.(new_cart))
end
end
describe "#apply_clearance" do
it "should take 20% off any item on clearance in the cart" do
old_cart = [{"AVOCADO" => {:price => 3.00,:clearance => true}}]
new_cart = [{"AVOCADO" => {:price => 2.40,:clearance => true}}]
expect(apply_clearance(old_cart)).to eq(new_cart)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment