Решение на Трета задача от Томислав Дюлгеров

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

Към профила на Томислав Дюлгеров

Резултати

  • 1 точка от тестове
  • 0 бонус точки
  • 1 точка общо
  • 2 успешни тест(а)
  • 17 неуспешни тест(а)

Код

class Inventory
require 'bigdecimal'
require 'bigdecimal/util'
MAX_PRICE = BigDecimal('999.99')
MIN_PRICE = BigDecimal('0.01')
MAX_LENGTH = 40
def initialize
@product_price = {}
@coupon_discount = {}
@product_promotion = {}
end
def register(product, price, promotion = {})
if product.length > MAX_LENGTH or @product_price.key? product \
or price.to_d < MIN_PRICE or price.to_d > MAX_PRICE
raise "Invalid parameters passed!"
end
@product_price[product] = price
@product_promotion[product] = promotion
end
def new_cart
Cart.new @product_price, @product_promotion, @coupon_discount
end
def register_coupon(name, discount)
@coupon_discount[name] = discount
end
end
class Cart
require 'bigdecimal'
require 'bigdecimal/util'
SECTION_DELIMITER = "+------------------------------------------------+----------+"
FIRST_ROW = "| Name qty | price |"
def initialize(inventory, promotion, coupon)
@product_quantity = {}
@product_to_price = inventory
@promotion_discount = promotion
@coupon_discount = coupon
end
def add(product, quantity = 1)
if not @product_to_price.key? product
raise "Product does not exist!"
end
if quantity > 99 or quantity <= 0
raise "Invalid quantity passed!"
end
if @product_quantity.key? product
@product_quantity[product] += quantity
else
@product_quantity[product] = quantity
end
end
def quantity_price
quantity_to_price = {}
@product_quantity.each do |key, value|
quantity_to_price[value] = @product_to_price[key]
end
quantity_to_price
end
def total
result = quantity_price.inject(0) { |sum, pair| sum + pair[0] * pair[1].to_d }
# apply promotions and coupons.
end
def use(coupon_name)
if @coupon_discount[coupon_name].nil?
raise "Coupon does not exist."
end
end
def display_products_and_discounts
@product_quantity.each do |key, value|
puts "| %s %#{45 - key.length}d |%9.2f |" % \
["#{key}", value, @product_to_price[key].to_d * value]
# display promotions if such exist.
end
# display coupon, if one is used.
end
def invoice
puts SECTION_DELIMITER, FIRST_ROW, SECTION_DELIMITER
display_products_and_discounts
puts SECTION_DELIMITER, \
"| TOTAL |" "%9.2f |" % "#{total}", \
SECTION_DELIMITER
end
end

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

..+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                    1 |     0.79 |
| Earl Grey                                    3 |     2.97 |
| Black Coffee                                 2 |     3.98 |
+------------------------------------------------+----------+
| TOTAL                                          |     7.74 |
+------------------------------------------------+----------+
FFF+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                    3 |     3.00 |
| Red Tea                                      8 |    16.00 |
+------------------------------------------------+----------+
| TOTAL                                          |    19.00 |
+------------------------------------------------+----------+
FFF+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                    4 |     4.00 |
| Red Tea                                      8 |    16.00 |
+------------------------------------------------+----------+
| TOTAL                                          |    20.00 |
+------------------------------------------------+----------+
FFF+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                   12 |    12.00 |
| Red Tea                                     20 |    40.00 |
+------------------------------------------------+----------+
| TOTAL                                          |    52.00 |
+------------------------------------------------+----------+
FFF+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                   10 |    10.00 |
+------------------------------------------------+----------+
| TOTAL                                          |    10.00 |
+------------------------------------------------+----------+
FFF+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                    5 |     5.00 |
+------------------------------------------------+----------+
| TOTAL                                          |     5.00 |
+------------------------------------------------+----------+
F+------------------------------------------------+----------+
| Name                                       qty |    price |
+------------------------------------------------+----------+
| Green Tea                                    8 |    22.32 |
| Black Coffee                                 5 |    14.95 |
| Milk                                         5 |     8.95 |
| Cereal                                       3 |     7.47 |
+------------------------------------------------+----------+
| TOTAL                                          |    38.74 |
+------------------------------------------------+----------+
F

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-17yjdmd/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 grants every nth item for free
     Failure/Error: cart.total.should eq '3.00'.to_d
       
       expected: #<BigDecimal:a7ae07c,'0.3E1',4(8)>
            got: #<BigDecimal:a7ae0b8,'0.4E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:93: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 'buy X, get one free' promotion grants 2 items free, when 8 purchased and every 3rd is free
     Failure/Error: cart.total.should eq '6.00'.to_d
       
       expected: #<BigDecimal:a7ad0c8,'0.6E1',4(8)>
            got: #<BigDecimal:a7ad104,'0.8E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:101: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 '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-17yjdmd/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)>'

  5) Inventory with a '% off for every n' promotion gives % off for every group of n
     Failure/Error: cart.total.should eq '3.20'.to_d
       
       expected: #<BigDecimal:a7aacec,'0.32E1',8(8)>
            got: #<BigDecimal:a7aad28,'0.4E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:131: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 for every n' promotion does not discount for extra items, that don't fit in a group
     Failure/Error: cart.total.should eq '1.80'.to_d
       
       expected: #<BigDecimal:a3b72e8,'0.18E1',8(8)>
            got: #<BigDecimal:a3b7324,'0.2E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:141: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 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-17yjdmd/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)>'

  8) 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:a3b4ee4,'0.154E2',8(8)>
            got: #<BigDecimal:a3b4f20,'0.16E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/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)>'

  9) 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:a82170c,'0.14E2',4(8)>
            got: #<BigDecimal:a821748,'0.15E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/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)>'

  10) 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-17yjdmd/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)>'

  11) Inventory with a '% off' coupon gives % off of the total
     Failure/Error: cart.total.should eq '8.00'.to_d
       
       expected: #<BigDecimal:a81f2cc,'0.8E1',4(8)>
            got: #<BigDecimal:a81f308,'0.1E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:220: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)>'

  12) Inventory with a '% off' coupon applies the coupon discount after product promotions
     Failure/Error: cart.total.should eq '9.00'.to_d
       
       expected: #<BigDecimal:a81e2c8,'0.9E1',4(8)>
            got: #<BigDecimal:a81e304,'0.12E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:230: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)>'

  13) 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-17yjdmd/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)>'

  14) Inventory with an 'amount off' coupon subtracts the amount form the total
     Failure/Error: cart.total.should eq '2.00'.to_d
       
       expected: #<BigDecimal:a83d7cc,'0.2E1',4(8)>
            got: #<BigDecimal:a83d808,'0.12E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:261: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)>'

  15) Inventory with an 'amount off' coupon does not result in a negative total
     Failure/Error: cart.total.should eq '0.00'.to_d
       
       expected: #<BigDecimal:a83c78c,'0.0',4(8)>
            got: #<BigDecimal:a83c7c8,'0.8E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-17yjdmd/spec.rb:271: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)>'

  16) 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-17yjdmd/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)>'

  17) 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-17yjdmd/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.57206 seconds
19 examples, 17 failures

Failed examples:

rspec /tmp/d20111115-5847-17yjdmd/spec.rb:64 # Inventory with no discounts can print an invoice
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:88 # Inventory with a 'buy X, get one free' promotion grants every nth item for free
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:96 # Inventory with a 'buy X, get one free' promotion grants 2 items free, when 8 purchased and every 3rd is free
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:104 # Inventory with a 'buy X, get one free' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:127 # Inventory with a '% off for every n' promotion gives % off for every group of n
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:137 # Inventory with a '% off for every n' promotion does not discount for extra items, that don't fit in a group
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:147 # Inventory with a '% off for every n' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-17yjdmd/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-17yjdmd/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-17yjdmd/spec.rb:190 # Inventory with a '% off of every item after the nth' promotion shows the discount in the ivnoice
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:213 # Inventory with a '% off' coupon gives % off of the total
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:223 # Inventory with a '% off' coupon applies the coupon discount after product promotions
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:233 # Inventory with a '% off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:254 # Inventory with an 'amount off' coupon subtracts the amount form the total
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:264 # Inventory with an 'amount off' coupon does not result in a negative total
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:274 # Inventory with an 'amount off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-17yjdmd/spec.rb:295 # Inventory with multiple discounts can print an invoice

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

Томислав обнови решението на 07.11.2011 15:31 (преди около 13 години)

+class Inventory
+ require 'bigdecimal'
+ require 'bigdecimal/util'
+
+ MAX_PRICE = BigDecimal('999.99')
+ MIN_PRICE = BigDecimal('0.01')
+ MAX_LENGTH = 40
+
+ def initialize
+ @product_price = {}
+ @coupon_discount = {}
+ @product_promotion = {}
+ end
+
+ def register(product, price, promotion = {})
+ if product.length > MAX_LENGTH or @product_price.key? product \
+ or price.to_d < MIN_PRICE or price.to_d > MAX_PRICE
+ raise "Invalid parameters passed!"
+ end
+ @product_price[product] = price
+ @product_promotion[product] = promotion
+ end
+
+ def new_cart
+ Cart.new @product_price, @product_promotion, @coupon_discount
+ end
+
+ def register_coupon(name, discount)
+ @coupon_discount[name] = discount
+ end
+end
+
+class Cart
+ require 'bigdecimal'
+ require 'bigdecimal/util'
+
+ SECTION_DELIMITER = "+------------------------------------------------+----------+"
+ FIRST_ROW = "| Name qty | price |"
+
+ def initialize(inventory, promotion, coupon)
+ @product_quantity = {}
+ @product_to_price = inventory
+ @promotion_discount = promotion
+ @coupon_discount = coupon
+ end
+
+ def add(product, quantity = 1)
+ if not @product_to_price.key? product
+ raise "Product does not exist!"
+ end
+ if quantity > 99 or quantity <= 0
+ raise "Invalid quantity passed!"
+ end
+ if @product_quantity.key? product
+ @product_quantity[product] += quantity
+ else
+ @product_quantity[product] = quantity
+ end
+ end
+
+ def quantity_price
+ quantity_to_price = {}
+ @product_quantity.each do |key, value|
+ quantity_to_price[value] = @product_to_price[key]
+ end
+ quantity_to_price
+ end
+
+ def total
+ result = quantity_price.inject(0) { |sum, pair| sum + pair[0] * pair[1].to_d }
+ # apply promotions and coupons.
+ end
+
+ def use(coupon_name)
+ if @coupon_discount[coupon_name].nil?
+ raise "Coupon does not exist."
+ end
+ end
+
+ def display_products_and_discounts
+ @product_quantity.each do |key, value|
+ puts "| %s %#{45 - key.length}d |%9.2f |" % \
+ ["#{key}", value, @product_to_price[key].to_d * value]
+ # display promotions if such exist.
+ end
+ # display coupon, if one is used.
+ end
+
+ def invoice
+ puts SECTION_DELIMITER, FIRST_ROW, SECTION_DELIMITER
+ display_products_and_discounts
+ puts SECTION_DELIMITER, \
+ "| TOTAL |" "%9.2f |" % "#{total}", \
+ SECTION_DELIMITER
+ end
+end