Решение на Трета задача от Петко Борджуков

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

Към профила на Петко Борджуков

Резултати

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

Код

require "bigdecimal"
require "bigdecimal/util"
class Product
MinPrice = "0.01".to_d
MaxPrice = "999.99".to_d
MaxName = 40
def initialize(info = {})
@info = {}
info.each {|key, value| self[key] = value}
end
def [](key)
@info[key.to_sym]
end
def []=(key, value)
key = key.to_sym
if key == :name
raise "Name length out of bounds" if value.length > MaxName
elsif key == :price
value = value.to_d
raise "Price out of range" if value < MinPrice or MaxPrice < value
end
@info[key] = value
end
end
class Cart
InvoiceSeparator = "+" + "-" * 48 + "+" + "-" * 10 + "+\n"
def initialize(inventory)
@inventory = inventory
@contents = {}
end
def add(name, quantity = 1)
raise "Quantity is out of bounds" unless quantity > 0 and quantity < 100
if @contents.include? name
@contents[name] += quantity
else
@contents[name] = @inventory.take(name, quantity)
end
end
def total
sum = BigDecimal.new("0")
@contents.each do |name, quantity|
sum += @inventory[name][:price] * quantity
end
p sum
sum
end
def invoice
result = InvoiceSeparator
result += autospace("Name", "qty", "price") + InvoiceSeparator
@contents.each do |name, quantity|
result += autospace(name, quantity,
"%.2f" % (quantity * @inventory[name][:price]).to_f)
end
result += InvoiceSeparator +
autospace("TOTAL", "", "%.2f" % total.to_f) + InvoiceSeparator
end
private
def autospace(name, quantity, price)
"| %-41s%5s | %8s |\n" %[name, quantity, price]
end
end
class Inventory
def initialize
@products = {}
end
def register(name, price, promo = {})
unless @products.include? name
@products[name] = Product.new name: name, price: price
else
raise "The product is already in the inventory"
end
end
alias :[]= :register
def [](name)
@products[name]
end
def take(name, quantity = 1)
if @products.include? name
quantity
else
raise "No such product, or insufficient not enough in stock"
end
end
def new_cart
Cart.new self
end
end

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

#<BigDecimal:98c0ed4,'0.398E1',8(16)>
..#<BigDecimal:9747cc4,'0.774E1',8(16)>
.#<BigDecimal:9a0c5cc,'0.4E1',4(12)>
F#<BigDecimal:9a0b67c,'0.8E1',4(12)>
F#<BigDecimal:9a0a344,'0.19E2',4(12)>
F#<BigDecimal:9a257d4,'0.4E1',4(12)>
F#<BigDecimal:9a24870,'0.2E1',4(12)>
F#<BigDecimal:9a23510,'0.2E2',4(12)>
F#<BigDecimal:93d4380,'0.16E2',4(12)>
F#<BigDecimal:93d341c,'0.8E1',4(12)>
#<BigDecimal:93d30fc,'0.1E2',4(12)>
#<BigDecimal:93d2ddc,'0.15E2',4(12)>
F#<BigDecimal:93d1a7c,'0.52E2',4(12)>
FFFFFFFF

Failures:

  1) 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:9a0c57c,'0.3E1',4(8)>
            got: #<BigDecimal:9a0c5cc,'0.4E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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)>'

  2) 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:9a0b62c,'0.6E1',4(8)>
            got: #<BigDecimal:9a0b67c,'0.8E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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)>'

  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 |     3.00 |\n| Red Tea                                      8 |    16.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    19.00 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       
       @@ -2,10 +2,8 @@
        | 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 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    16.00 |
       +| TOTAL                                          |    19.00 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-gsfucq/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:9a25784,'0.32E1',8(8)>
            got: #<BigDecimal:9a257d4,'0.4E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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:9a24820,'0.18E1',8(8)>
            got: #<BigDecimal:9a24870,'0.2E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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 |     4.00 |\n| Red Tea                                      8 |    16.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    20.00 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       
       @@ -2,10 +2,8 @@
        | 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 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    17.60 |
       +| TOTAL                                          |    20.00 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-gsfucq/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:93d4330,'0.154E2',8(8)>
            got: #<BigDecimal:93d4380,'0.16E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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:93d2d8c,'0.14E2',4(8)>
            got: #<BigDecimal:93d2ddc,'0.15E2',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-gsfucq/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 |    12.00 |\n| Red Tea                                     20 |    40.00 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    52.00 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       
       @@ -2,10 +2,8 @@
        | 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 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    49.80 |
       +| TOTAL                                          |    52.00 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-gsfucq/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:0x93f26c8>
     # /tmp/d20111115-5847-gsfucq/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:0x93f1bc4>
     # /tmp/d20111115-5847-gsfucq/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:0x93f11c4>
     # /tmp/d20111115-5847-gsfucq/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:0x979de94>
     # /tmp/d20111115-5847-gsfucq/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:0x979d354>
     # /tmp/d20111115-5847-gsfucq/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:0x979c918>
     # /tmp/d20111115-5847-gsfucq/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:0x979bc48>
     # /tmp/d20111115-5847-gsfucq/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.56667 seconds
19 examples, 16 failures

Failed examples:

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

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

Петко обнови решението на 07.11.2011 15:45 (преди над 12 години)

+require "bigdecimal"
+require "bigdecimal/util"
+class Product
+ MinPrice = "0.01".to_d
+ MaxPrice = "999.99".to_d
+ MaxName = 40
+ def initialize(info = {})
+ @info = {}
+ info.each {|key, value| self[key] = value}
+ end
+ def [](key)
+ @info[key.to_sym]
+ end
+ def []=(key, value)
+ key = key.to_sym
+ if key == :name
+ raise "Name length out of bounds" if value.length > MaxName
+ elsif key == :price
+ value = value.to_d
+ raise "Price out of range" if value < MinPrice or MaxPrice < value
+ end
+ @info[key] = value
+ end
+end
+class Cart
+ InvoiceSeparator = "+" + "-" * 48 + "+" + "-" * 10 + "+\n"
+ def initialize(inventory)
+ @inventory = inventory
+ @contents = {}
+ end
+ def add(name, quantity = 1)
+ raise "Quantity is out of bounds" unless quantity > 0 and quantity < 100
+ if @contents.include? name
+ @contents[name] += quantity
+ else
+ @contents[name] = @inventory.take(name, quantity)
+ end
+ end
+ def total
+ sum = BigDecimal.new("0")
+ @contents.each do |name, quantity|
+ sum += @inventory[name][:price] * quantity
+ end
+ p sum
+ sum
+ end
+ def invoice
+ result = InvoiceSeparator
+ result += autospace("Name", "qty", "price") + InvoiceSeparator
+ @contents.each do |name, quantity|
+ result += autospace(name, quantity,
+ "%.2f" % (quantity * @inventory[name][:price]).to_f)
+ end
+ result += InvoiceSeparator +
+ autospace("TOTAL", "", "%.2f" % total.to_f) + InvoiceSeparator
+ end
+ private
+ def autospace(name, quantity, price)
+ "| %-41s%5s | %8s |\n" %[name, quantity, price]
+ end
+end
+
+class Inventory
+ def initialize
+ @products = {}
+ end
+ def register(name, price, promo = {})
+ unless @products.include? name
+ @products[name] = Product.new name: name, price: price
+ else
+ raise "The product is already in the inventory"
+ end
+ end
+ alias :[]= :register
+ def [](name)
+ @products[name]
+ end
+ def take(name, quantity = 1)
+ if @products.include? name
+ quantity
+ else
+ raise "No such product, or insufficient not enough in stock"
+ end
+ end
+ def new_cart
+ Cart.new self
+ end
+end