Last active
December 18, 2015 11:59
-
-
Save deatheragetr/5779432 to your computer and use it in GitHub Desktop.
grocery code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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