Решение на Трета задача от Ангел Миланов

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

Към профила на Ангел Миланов

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Inventory
def initialize
@inventory={}
@promotion={}
end
def register (product,cost,_promotion={})
validcost=cost.to_d>=0.01 and cost.to_d<=999.99
if validcost and product.size<40 and not @inventory.key? product
@inventory[product]=cost
@promotion[product]=_promotion
else
raise "Invalid parameters passed."
end
end
def new_cart
Cart.new(@inventory,@promotion)
end
end
class Cart
def initialize(_inventory,_promotion)
@inventory=_inventory
@promotion=_promotion
@cart=Hash.new(0)
end
def add (product,qty=1)
if @inventory.key? product and qty>0 and qty+@cart[product]<99
@cart[product]+=qty
else
raise "Invalid parameters passed."
end
end
def total
result=BigDecimal('0.00')
@cart.each do |key,value|
result+=@cart[key]*@inventory[key].to_d
if @promotion[key].has_key? :get_one_free
result-=@cart[key]/@promotion[key][:get_one_free]*@inventory[key].to_d
end
end
result
end
def invoice
result="+"+"-"*48+"+"+"-"*10+"+\n"+"| "+"Name"+" "*39+"qty | price |\n"
result+="+"+"-"*48+"+"+"-"*10+"+"
@cart.each do |key, value|
result+=print_product key ,value
end
result+=print_total
end
def print_product(key,value)
string="\n|"+" #{key}"+" "*(46-" #{key}".size)+"#{@cart[key]} |"
string+=" "*(9-"#{@inventory[key]}".size)+"#{@inventory[key]} |"
end
def print_total
result="\n+"+"-"*48+"+"+"-"*10+"+\n"+"| TOTAL"+" "*42
result+="|"+" "*(9-"#{total.round(2).to_f}".size)+"#{total.round(2).to_f} |\n"
result+="+"+"-"*48+"+"+"-"*10+"+"
end
def print_promotion(key)
if @promotion[key].has_key? :get_one_free
string="\n| (buy #{@promotion[key][:get_one_free]}"
string+=", get 1 free) "
discount=@cart[key]/@promotion[key][:get_one_free]*@inventory[key].to_d
string+="|"+" "*(9-"-#{discount.to_f}".size)+"-#{discount.to_f} |"
end
string
end
end

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

.FF..FFFFFFFFFFFFFF

Failures:

  1) Inventory with no discounts has some constraints on prices and counts
     Failure/Error: inventory.register 'A' * 40, '1.99'
     RuntimeError:
       Invalid parameters passed.
     # /tmp/d20111115-5847-1o0tmyx/solution.rb:17:in `register'
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:50: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 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    1 |     0.79 |\n| Earl Grey                                    3 |     0.99 |\n| Black Coffee                                 2 |     1.99 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     7.74 |\n+------------------------------------------------+----------+"
       
       (compared using ==)
       
       Diff:
       @@ -2,8 +2,8 @@
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
        | Green Tea                                    1 |     0.79 |
       -| Earl Grey                                    3 |     2.97 |
       -| Black Coffee                                 2 |     3.98 |
       +| Earl Grey                                    3 |     0.99 |
       +| Black Coffee                                 2 |     1.99 |
        +------------------------------------------------+----------+
        | TOTAL                                          |     7.74 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  3) 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    3 |     1.00 |\n| Red Tea                                      8 |     2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     16.0 |\n+------------------------------------------------+----------+"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,9 @@
        +------------------------------------------------+----------+
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
       -| Green Tea                                    3 |     3.00 |
       -|   (buy 2, get 1 free)                          |    -1.00 |
       -| Red Tea                                      8 |    16.00 |
       -|   (buy 4, get 1 free)                          |    -2.00 |
       +| Green Tea                                    3 |     1.00 |
       +| Red Tea                                      8 |     2.00 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    16.00 |
       +| TOTAL                                          |     16.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  4) 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:96c9e8c,'0.32E1',8(8)>
            got: #<BigDecimal:96c9ec8,'0.4E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  5) 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:96c8e9c,'0.18E1',8(8)>
            got: #<BigDecimal:96c8ed8,'0.2E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  6) 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    4 |     1.00 |\n| Red Tea                                      8 |     2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     20.0 |\n+------------------------------------------------+----------+"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,9 @@
        +------------------------------------------------+----------+
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
       -| Green Tea                                    4 |     4.00 |
       -|   (get 10% off for every 4)                    |    -0.40 |
       -| Red Tea                                      8 |    16.00 |
       -|   (get 20% off for every 5)                    |    -2.00 |
       +| Green Tea                                    4 |     1.00 |
       +| Red Tea                                      8 |     2.00 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    17.60 |
       +| TOTAL                                          |     20.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  7) 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:93b6650,'0.154E2',8(8)>
            got: #<BigDecimal:93b668c,'0.16E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  8) 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:93b4fd0,'0.14E2',4(8)>
            got: #<BigDecimal:93b500c,'0.15E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  9) 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    12 |     1.00 |\n| Red Tea                                      20 |     2.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     52.0 |\n+------------------------------------------------+----------+"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,9 @@
        +------------------------------------------------+----------+
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
       -| Green Tea                                   12 |    12.00 |
       -|   (10% off of every after the 10th)            |    -0.20 |
       -| Red Tea                                     20 |    40.00 |
       -|   (20% off of every after the 15th)            |    -2.00 |
       +| Green Tea                                    12 |     1.00 |
       +| Red Tea                                      20 |     2.00 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    49.80 |
       +| TOTAL                                          |     52.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-1o0tmyx/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)>'

  10) Inventory with a '% off' coupon gives % off of the total
     Failure/Error: inventory.register_coupon 'TEATIME', percent: 20
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x935605c>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:215: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 applies the coupon discount after product promotions
     Failure/Error: inventory.register_coupon 'TEATIME', percent: 10
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x93554f4>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:225: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 shows the discount in the invoice
     Failure/Error: inventory.register_coupon 'TEA-TIME', percent: 20
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x9375100>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:235: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 an 'amount off' coupon subtracts the amount form the total
     Failure/Error: inventory.register_coupon 'TEATIME', amount: '10.00'.to_d
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x9374408>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:256: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 does not result in a negative total
     Failure/Error: inventory.register_coupon 'TEATIME', amount: '10.00'.to_d
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x9373864>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:266: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 shows the discount in the invoice
     Failure/Error: inventory.register_coupon 'TEA-TIME', amount: '10.00'.to_d
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x9372dc4>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:276: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 multiple discounts can print an invoice
     Failure/Error: inventory.register_coupon 'BREAKFAST', percent: 10
     NoMethodError:
       undefined method `register_coupon' for #<Inventory:0x9372090>
     # /tmp/d20111115-5847-1o0tmyx/spec.rb:301: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.55917 seconds
19 examples, 16 failures

Failed examples:

rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:47 # Inventory with no discounts has some constraints on prices and counts
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:64 # Inventory with no discounts can print an invoice
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:104 # Inventory with a 'buy X, get one free' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:127 # Inventory with a '% off for every n' promotion gives % off for every group of n
rspec /tmp/d20111115-5847-1o0tmyx/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-1o0tmyx/spec.rb:147 # Inventory with a '% off for every n' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-1o0tmyx/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-1o0tmyx/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-1o0tmyx/spec.rb:190 # Inventory with a '% off of every item after the nth' promotion shows the discount in the ivnoice
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:213 # Inventory with a '% off' coupon gives % off of the total
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:223 # Inventory with a '% off' coupon applies the coupon discount after product promotions
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:233 # Inventory with a '% off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:254 # Inventory with an 'amount off' coupon subtracts the amount form the total
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:264 # Inventory with an 'amount off' coupon does not result in a negative total
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:274 # Inventory with an 'amount off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-1o0tmyx/spec.rb:295 # Inventory with multiple discounts can print an invoice

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

Ангел обнови решението на 07.11.2011 15:59 (преди над 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Inventory
+ def initialize
+ @inventory={}
+ @promotion={}
+ end
+
+
+ def register (product,cost,_promotion={})
+ validcost=cost.to_d>=0.01 and cost.to_d<=999.99
+ if validcost and product.size<40 and not @inventory.key? product
+ @inventory[product]=cost
+ @promotion[product]=_promotion
+ else
+ raise "Invalid parameters passed."
+ end
+ end
+
+
+ def new_cart
+ Cart.new(@inventory,@promotion)
+ end
+end
+
+
+class Cart
+ def initialize(_inventory,_promotion)
+ @inventory=_inventory
+ @promotion=_promotion
+ @cart=Hash.new(0)
+ end
+
+
+ def add (product,qty=1)
+ if @inventory.key? product and qty>0 and qty+@cart[product]<99
+ @cart[product]+=qty
+ else
+ raise "Invalid parameters passed."
+ end
+ end
+
+
+ def total
+ result=BigDecimal('0.00')
+ @cart.each do |key,value|
+ result+=@cart[key]*@inventory[key].to_d
+ if @promotion[key].has_key? :get_one_free
+ result-=@cart[key]/@promotion[key][:get_one_free]*@inventory[key].to_d
+ end
+ end
+ result
+ end
+
+
+ def invoice
+ result="+"+"-"*48+"+"+"-"*10+"+\n"+"| "+"Name"+" "*39+"qty | price |\n"
+ result+="+"+"-"*48+"+"+"-"*10+"+"
+ @cart.each do |key, value|
+ result+=print_product key ,value
+ end
+ result+=print_total
+ end
+
+
+ def print_product(key,value)
+ string="\n|"+" #{key}"+" "*(46-" #{key}".size)+"#{@cart[key]} |"
+ string+=" "*(9-"#{@inventory[key]}".size)+"#{@inventory[key]} |"
+ end
+
+
+ def print_total
+ result="\n+"+"-"*48+"+"+"-"*10+"+\n"+"| TOTAL"+" "*42
+ result+="|"+" "*(9-"#{total.round(2).to_f}".size)+"#{total.round(2).to_f} |\n"
+ result+="+"+"-"*48+"+"+"-"*10+"+"
+ end
+
+
+ def print_promotion(key)
+ if @promotion[key].has_key? :get_one_free
+ string="\n| (buy #{@promotion[key][:get_one_free]}"
+ string+=", get 1 free) "
+ discount=@cart[key]/@promotion[key][:get_one_free]*@inventory[key].to_d
+ string+="|"+" "*(9-"-#{discount.to_f}".size)+"-#{discount.to_f} |"
+ end
+ string
+ end
+end