Skip to content

Instantly share code, notes, and snippets.

@deatheragetr
Last active December 18, 2015 11:59
Show Gist options
  • Save deatheragetr/5779432 to your computer and use it in GitHub Desktop.
Save deatheragetr/5779432 to your computer and use it in GitHub Desktop.
grocery code
require 'ap'
##################################################################
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 items
def generateCart
cart = []
rand(20).times do
cart.push(ITEMS.sample)
end
cart
end
##randomly generates set of coupons
def generateCoups
coups = []
rand(11).times do
coups.push(COUPS.sample)
end
coups
end
#############################################################
#First things first convert the array ITEMS into a hash with nested
# where keys are the the item ("AVOCADO", "KALE", etc.) and values are
# hashes of attributes that include a count attribute which indicates the frequency of
# that particular item
#Gonna just hard code for now, maybe make more functional and modular later...
cart = generateCart
coupons = generateCoups
cart_hash = {}
# puts ap cart
cart.each do |item_hash|
item_hash.each do |name, attributes|
(cart_hash[name] = attributes) unless cart_hash[name]
cart_hash[name][:count] ||= 0
cart_hash[name][:count] += 1
end
end
# puts ap cart_hash
coupons_hash = {}
coupons.each do |coupon|
if coupons_hash[coupon[:item]]
coupons_hash[coupon[:item]][:count] += 1
else
coupons_hash[coupon[:item]] = {:num => coupon[:num], :cost => coupon[:cost], :count => 1}
end
end
# ^^ So that seems to work. cool.
####
#Okay, so now I'm gonna write a method that can be called from the checkout method
# to apply an appropriate discount based on the presence of coupons
# This'll get a little hairy so I'm actually gonna break it up into at least two functions
# One method contains a nested iterations. The Wrapping iterations goes through each
# coupon. The inner iteration goes through each item in the cart and checks to see
# the coupon can be applied.
# Next I need a method that can be called that can actually apply the appropriate
# discount.
# {:item=>"BEER", :num=>2, :cost=>20.0} <-- What I'm working with here (coupons).
# {"PEANUTBUTTER"=>{:price=>3.0, :clearance=>true, :count=>1}} <-- cart_hash
# So I want to apply the coupon discount but I don't want to apply the discount
# to more items than x where :num=> x. So, I think what i'll do here is
# first create a method that appends a discount (probably a negative integer)
# attribute to the proper hashes in cart_hash
# There are some peculiar situations that are possible in this example
# For one, if a customer has two of the same kind of coupon then the
# coupon discount is tripled. I interpret this to mean that if the customer has
# at least x amount of grocery items (where coupons_hash[item_name][:num] => x) and
# two of the same coupons (that is, coupons_hash[item_name][:count] >= 2) then
# the discount will be tripled. However, I highly doubt, if this scenario is to be kind of
# realistic, that more coupons will create a larger discount.
# so let me right this out in pseudo code
# if count of grocery_items is greater than the corresponding coupons
# :num attribute apply a discount attribute to the cart_hash
# if the above is true, and there at least two coupons of the same type, triple the discount
# however, the discount maxes out here.
def append_discount_attribute coupon_name ,coupon_data, cart_hash
couponed_price_per_unit = coupon_data[:cost] / coupon_data[:num]
discount = -1 * (cart_hash[coupon_name][:price] - couponed_price_per_unit)*coupon_data[:num]
cart_hash[coupon_name][:discount] = discount
if coupon_data[:count] >= 2
cart_hash[coupon_name][:discount] *= 3
end
cart_hash
end
def apply_coupons(coupons_hash, cart_hash)
coupons_hash.each do |coupon, data|
cart_hash.each do |item, attribute|
if coupon == item && attribute[:count] >= data[:num]
cart_hash = append_discount_attribute coupon, data, cart_hash
end
end
end
cart_hash
end
# puts coupons
# puts ap apply_coupons coupons, cart_hash
# ########
# applies a a 20% discount to each item if clearance = true
def apply_clearance (cart_hash)
cart_hash.each do |item, attributes|
if attributes[:clearance] == true
attributes[:clearance_discount] = -1 * 0.2 *(attributes[:price] * attributes[:count])
end
end
cart_hash
end
# puts ap apply_clearance(cart_hash)
# Next let's work on a total a checkout method that calculates total cost of all the items in
# the cart_hash
# puts cart_hash
def sum_discounts (cart_hash, coupons_hash)
discount = 0
cart_hash = apply_coupons coupons_hash, apply_clearance(cart_hash)
cart_hash.each do |item, attributes|
if attributes[:discount]
discount += attributes[:discount]
end
if attributes[:clearance_discount]
discount += attributes[:clearance_discount]
end
end
discount
end
def checkout(cart_hash, coupons_hash)
total = 0
cart_hash.each do |item, attributes|
total += attributes[:count] * attributes[:price]
end
discount = sum_discounts cart_hash, coupons_hash
puts "SubTotal is #{total}"
puts "discount is #{discount}"
total += discount
total.round(2)
end
puts "total is $#{checkout(cart_hash, coupons_hash)}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment