Решение на Трета задача от Теодор Николов

Обратно към всички решения

Към профила на Теодор Николов

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 10 успешни тест(а)
  • 9 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Product
attr_reader :name, :price, :promotion
def initialize(name, price, promotion = {})
raise "You can assign only one promotion" if promotion.size > 1
@name = name.strip
@price = price.to_d
@promotion = promotion
end
end
class Inventory
attr_reader :coupons, :products
def initialize
@products = []
@coupons = {}
end
def register(name, price, promotion = {})
if name.size <= 40 and price.to_d >= '0.01'.to_d and price.to_d <= '999.99'.to_d
if exists?(name)
raise "Existing product"
else
@products << Product.new(name, price, promotion)
end
else
raise "Invalid argumen given"
end
end
def register_coupon(coupon_name, discount)
@coupons[coupon_name] = discount
end
def new_cart
return Cart.new(self)
end
def exists?(name)
if @products.any? { |product| product.name.downcase == name.strip.downcase}
true
else
false
end
end
end
class CartProduct
attr_reader :name
attr_accessor :qty
def initialize(name,qty)
if qty > 99
raise "Product quantity is too big"
end
@name = name.strip
@qty = qty
end
end
class Cart < Inventory
def initialize(inventory)
@inventory = inventory
@products = []
@coupon = ''
end
def add(name, qty = 1)
raise "Invalid quantity" if qty < 1
if exists? (name)
change_product_qty(name, qty)
elsif @inventory.exists? name
@products << CartProduct.new(name, qty)
else
raise "Product doesn`t exist"
end
end
def change_product_qty(name, qty)
@products.each do |product|
product.qty += qty if product.name.downcase == name.downcase
if product.qty > 99
product.qty -= qty
raise "Product quantity is too big"
end
end
end
def use(coupon)
if @inventory.coupons.has_key? coupon
@coupon = coupon
end
end
def total
price = '0'.to_d
@products.each do |product|
price += get_price_with_discount(product.name, product.qty)
end
if @coupon != ""
if @inventory.coupons[@coupon].keys[0] == :amount
price -= [@inventory.coupons[@coupon].values[0], price].min
else
price -= price/100*@inventory.coupons[@coupon].values[0]
end
end
price
end
def get_price_with_discount(name, qty)
product = @inventory.products.select{ |product| product.name == name }[0]
price = qty*product.price
price = get_price_by_promotion(product, qty) if !product.promotion.empty?
return price
end
def get_price_by_promotion(product, qty)
if product.promotion.keys[0] == :get_one_free
return (qty - qty/product.promotion.values[0])*product.price
elsif product.promotion.keys[0] == :threshold
get_price_by_threshold(product, qty)
elsif product.promotion.keys[0] == :package
get_price_by_package(product, qty)
else
return qty*product.price
end
end
def get_price_by_threshold(product, qty)
if product.promotion.values[0].keys[0] >= qty
qty*product.price
else
num = product.promotion.values[0].keys[0]
price = num*product.price
price += (qty-num)*(product.price/100*product.promotion.values[0].values[0])
end
end
def get_price_by_package(product, qty)
discount_hash = product.promotion.values[0]
discount = discount_hash.keys[0]*product.price/100*discount_hash.values[0]
qty*product.price - qty/discount_hash.keys[0]*discount
end
def invoice
end
end

Лог от изпълнението

..F..F..FFFF..F..FF

Failures:

  1) Inventory with no discounts can print an invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    1 |     0.79 |\n| Earl Grey                                    3 |     2.97 |\n| Black Coffee                                 2 |     3.98 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     7.74 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:73:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Inventory with a 'buy X, get one free' promotion shows the discount in the invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    3 |     3.00 |\n|   (buy 2, get 1 free)                          |    -1.00 |\n| Red Tea                                      8 |    16.00 |\n|   (buy 4, get 1 free)                          |    -2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    16.00 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:111:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) Inventory with a '% off for every n' promotion shows the discount in the invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    4 |     4.00 |\n|   (get 10% off for every 4)                    |    -0.40 |\n| Red Tea                                      8 |    16.00 |\n|   (get 20% off for every 5)                    |    -2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    17.60 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:154:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) Inventory with a '% off of every item after the nth' promotion gives a discount for every item after the nth
     Failure/Error: cart.total.should eq '15.40'.to_d
       
       expected: #<BigDecimal:9ada7b0,'0.154E2',8(8)>
            got: #<BigDecimal:9ada800,'0.106E2',8(16)>
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:174:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) Inventory with a '% off of every item after the nth' promotion does not give a discount if there are no more than n items in the cart
     Failure/Error: cart.total.should eq '14.00'.to_d
       
       expected: #<BigDecimal:9ad8bb8,'0.14E2',4(8)>
            got: #<BigDecimal:9ad8c08,'0.11E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:187:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) Inventory with a '% off of every item after the nth' promotion shows the discount in the ivnoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                   12 |    12.00 |\n|   (10% off of every after the 10th)            |    -0.20 |\n| Red Tea                                     20 |    40.00 |\n|   (20% off of every after the 15th)            |    -2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    49.80 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:197:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) Inventory with a '% off' coupon shows the discount in the invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                   10 |    10.00 |\n| Coupon TEA-TIME - 20% off                      |    -2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     8.00 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:240:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) Inventory with an 'amount off' coupon shows the discount in the invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    5 |     5.00 |\n| Coupon TEA-TIME - 10.00 off                    |    -5.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     0.00 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:281:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  9) Inventory with multiple discounts can print an invoice
     Failure/Error: cart.invoice.should eq <<INVOICE
       
       expected: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    8 |    22.32 |\n|   (buy 1, get 1 free)                          |   -11.16 |\n| Black Coffee                                 5 |    14.95 |\n|   (get 20% off for every 2)                    |    -2.39 |\n| Milk                                         5 |     8.95 |\n|   (30% off of every after the 3rd)             |    -1.07 |\n| Cereal                                       3 |     7.47 |\n| Coupon BREAKFAST - 10% off                     |    -3.91 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    35.16 |\n+------------------------------------------------+----------+\n"
            got: nil
       
       (compared using ==)
     # /tmp/d20111115-5847-2rdyk8/spec.rb:309:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.56738 seconds
19 examples, 9 failures

Failed examples:

rspec /tmp/d20111115-5847-2rdyk8/spec.rb:64 # Inventory with no discounts can print an invoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:104 # Inventory with a 'buy X, get one free' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:147 # Inventory with a '% off for every n' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:170 # Inventory with a '% off of every item after the nth' promotion gives a discount for every item after the nth
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:177 # Inventory with a '% off of every item after the nth' promotion does not give a discount if there are no more than n items in the cart
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:190 # Inventory with a '% off of every item after the nth' promotion shows the discount in the ivnoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:233 # Inventory with a '% off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:274 # Inventory with an 'amount off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-2rdyk8/spec.rb:295 # Inventory with multiple discounts can print an invoice

История (1 версия и 0 коментара)

Теодор обнови решението на 07.11.2011 00:45 (преди около 13 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Product
+ attr_reader :name, :price, :promotion
+ def initialize(name, price, promotion = {})
+ raise "You can assign only one promotion" if promotion.size > 1
+ @name = name.strip
+ @price = price.to_d
+ @promotion = promotion
+ end
+
+end
+
+class Inventory
+ attr_reader :coupons, :products
+ def initialize
+ @products = []
+ @coupons = {}
+ end
+ def register(name, price, promotion = {})
+ if name.size <= 40 and price.to_d >= '0.01'.to_d and price.to_d <= '999.99'.to_d
+ if exists?(name)
+ raise "Existing product"
+ else
+ @products << Product.new(name, price, promotion)
+ end
+ else
+ raise "Invalid argumen given"
+ end
+ end
+
+ def register_coupon(coupon_name, discount)
+ @coupons[coupon_name] = discount
+ end
+
+ def new_cart
+ return Cart.new(self)
+ end
+
+ def exists?(name)
+ if @products.any? { |product| product.name.downcase == name.strip.downcase}
+ true
+ else
+ false
+ end
+ end
+end
+
+class CartProduct
+ attr_reader :name
+ attr_accessor :qty
+ def initialize(name,qty)
+ if qty > 99
+ raise "Product quantity is too big"
+ end
+ @name = name.strip
+ @qty = qty
+ end
+end
+
+class Cart < Inventory
+ def initialize(inventory)
+ @inventory = inventory
+ @products = []
+ @coupon = ''
+ end
+
+ def add(name, qty = 1)
+ raise "Invalid quantity" if qty < 1
+ if exists? (name)
+ change_product_qty(name, qty)
+ elsif @inventory.exists? name
+ @products << CartProduct.new(name, qty)
+ else
+ raise "Product doesn`t exist"
+ end
+ end
+
+ def change_product_qty(name, qty)
+ @products.each do |product|
+ product.qty += qty if product.name.downcase == name.downcase
+ if product.qty > 99
+ product.qty -= qty
+ raise "Product quantity is too big"
+ end
+ end
+ end
+
+ def use(coupon)
+ if @inventory.coupons.has_key? coupon
+ @coupon = coupon
+ end
+ end
+
+ def total
+ price = '0'.to_d
+ @products.each do |product|
+ price += get_price_with_discount(product.name, product.qty)
+ end
+ if @coupon != ""
+ if @inventory.coupons[@coupon].keys[0] == :amount
+ price -= [@inventory.coupons[@coupon].values[0], price].min
+ else
+ price -= price/100*@inventory.coupons[@coupon].values[0]
+ end
+ end
+ price
+ end
+
+
+ def get_price_with_discount(name, qty)
+ product = @inventory.products.select{ |product| product.name == name }[0]
+ price = qty*product.price
+ price = get_price_by_promotion(product, qty) if !product.promotion.empty?
+ return price
+ end
+
+ def get_price_by_promotion(product, qty)
+ if product.promotion.keys[0] == :get_one_free
+ return (qty - qty/product.promotion.values[0])*product.price
+ elsif product.promotion.keys[0] == :threshold
+ get_price_by_threshold(product, qty)
+ elsif product.promotion.keys[0] == :package
+ get_price_by_package(product, qty)
+ else
+ return qty*product.price
+ end
+ end
+
+ def get_price_by_threshold(product, qty)
+ if product.promotion.values[0].keys[0] >= qty
+ qty*product.price
+ else
+ num = product.promotion.values[0].keys[0]
+ price = num*product.price
+ price += (qty-num)*(product.price/100*product.promotion.values[0].values[0])
+ end
+ end
+
+ def get_price_by_package(product, qty)
+ discount_hash = product.promotion.values[0]
+ discount = discount_hash.keys[0]*product.price/100*discount_hash.values[0]
+ qty*product.price - qty/discount_hash.keys[0]*discount
+ end
+
+ def invoice
+
+ end
+end