Решение на Трета задача от Мая Лекова

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

Към профила на Мая Лекова

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 12 успешни тест(а)
  • 7 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Cart
def initialize(products, promos, coupons)
@order = Hash.new(0)
@products = products
@promos = promos
@coupons = coupons
end
def add(name, quantity = 1)
if !@products.has_key? name or !(@order[name] + quantity).between?(1, 99)
raise "Invalid parameters passed."
end
@order[name] += quantity
end
def raw_total
price_total = 0
@order.map { |name, quantity| price_total +=
@promos[name].total(quantity, @products[name].to_d) }
price_total
end
def total
raw_total + (@used_coupon ? @used_coupon.discount(raw_total) : 0)
end
def invoice
@@line + @@header + @@line +
(@order.keys.map { |v| entry_to_s v }.inject("") { |s1, s2| s1 + s2 }) +
(@used_coupon ? @used_coupon.coupon_to_s(raw_total) : "") +
@@line + footer + @@line
end
def use(name)
@used_coupon = Coupon.new(name, @coupons[name])
end
@@line = "+------------------------------------------------+----------+\n"
@@header = "| Name qty | price |\n"
def raw_price(name)
@products[name].to_d * @order[name]
end
def footer
"| TOTAL | " +
total.truncate(2).to_s('F').rjust(8) + " |\n"
end
def entry_to_s(name)
"| " + name + @order[name].to_s.rjust(46 - name.length) + " | " +
raw_price(name).truncate(2).to_s('F').rjust(8) + " |\n" +
@promos[name].promo_to_s(@order[name], @products[name].to_d)
end
end
class Coupon
def initialize(name, spec)
@name = name
if spec.keys[0] == :percent
@percent = spec.values[0]
elsif spec.keys[0] == :amount
@amount = spec.values[0]
end
end
def coupon_to_s(price)
("| Coupon " + @name + " - " + discount_to_s + " off").ljust(48) +
" |" + discount(price).truncate(2).to_s('F').rjust(8) + " |\n"
end
def discount_to_s
if @percent
@percent.to_s + "%"
elsif @amount
@amount.to_s
else
""
end
end
def discount(price)
if @percent
-price * @percent / BigDecimal("100.0")
elsif @amount
-(@amount.to_d)
else
0
end
end
end
class Promo
def total(quantity, price)
quantity * price + discount(quantity, price)
end
def promo_to_s(quantity, price)
""
end
end
class StandardPrice < Promo
def discount(quantity, price)
0
end
end
class GetOneFree < Promo
def initialize(count)
@count = count
end
def discount(quantity, price)
-(quantity / @count) * price
end
def promo_to_s(quantity, price)
("| (buy " + (count - 1).to_s + ", get 1 free)").ljust(48) + " | " +
discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
end
attr_reader :count
end
class Package < Promo
def initialize(spec)
@count = spec.keys[0]
@percent = spec.values[0]
end
def discount(quantity, price)
-((quantity / @count) * @count * @percent * price) / BigDecimal("100.0")
end
def promo_to_s(quantity, price)
("| (get " + @percent.to_s + "% off for every " + @count.to_s + ")").ljust(48) +
" | " + discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
end
attr_reader :count, :percent
end
class Threshold < Promo
def initialize(spec)
@count = spec.keys[0]
@percent = spec.values[0]
end
def discount(quantity, price)
if quantity <= count
return BigDecimal.new("0")
end
-((quantity - count) * price * @percent) / BigDecimal("100.0")
end
def promo_to_s(quantity, price)
descr = "% off of every after the "
("| (" + @percent.to_s + descr + count_to_s + ")").ljust(48) +
" | " + discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
end
def count_to_s
if count == 1
"1st"
elsif count == 2
"2nd"
elsif count == 3
"3rd"
else
@count.to_s + "th"
end
end
attr_reader :count, :percent
end
class Inventory
def initialize()
@products = {}
@promos = {}
@coupons = {}
end
def register(name, price, promo = {})
if name.length > 40 or !price.to_d.between?(0.01, 999.99) or @products.has_key? name
raise "Invalid parameters passed."
end
@products[name] = price
handle_promos promo, name
end
def handle_promos(promo, name)
if promo.has_key? :get_one_free
@promos[name] = GetOneFree.new(promo[:get_one_free])
elsif promo.has_key? :package
@promos[name] = Package.new(promo[:package])
elsif promo.has_key? :threshold
@promos[name] = Threshold.new(promo[:threshold])
else
@promos[name] = StandardPrice.new
end
end
def register_coupon(name, spec)
@coupons[name] = spec
end
def new_cart
return Cart.new(@products, @promos, @coupons)
end
end

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

.....F..F..F..F.FFF

Failures:

  1) 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.0 |\n|   (buy 2, get 1 free)                          |     -1.0 |\n| Red Tea                                      8 |     16.0 |\n|   (buy 4, get 1 free)                          |     -2.0 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     16.0 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,11 @@
        +------------------------------------------------+----------+
        | 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 |      3.0 |
       +|   (buy 2, get 1 free)                          |     -1.0 |
       +| Red Tea                                      8 |     16.0 |
       +|   (buy 4, get 1 free)                          |     -2.0 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    16.00 |
       +| TOTAL                                          |     16.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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)>'

  2) 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.0 |\n|   (get 10% off for every 4)                    |     -0.4 |\n| Red Tea                                      8 |     16.0 |\n|   (get 20% off for every 5)                    |     -2.0 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     17.6 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,11 @@
        +------------------------------------------------+----------+
        | 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 |      4.0 |
       +|   (get 10% off for every 4)                    |     -0.4 |
       +| Red Tea                                      8 |     16.0 |
       +|   (get 20% off for every 5)                    |     -2.0 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    17.60 |
       +| TOTAL                                          |     17.6 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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)>'

  3) 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.0 |\n|   (10% off of every after the 10th)            |     -0.2 |\n| Red Tea                                     20 |     40.0 |\n|   (20% off of every after the 15th)            |     -2.0 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     49.8 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,11 +1,11 @@
        +------------------------------------------------+----------+
        | 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 |     12.0 |
       +|   (10% off of every after the 10th)            |     -0.2 |
       +| Red Tea                                     20 |     40.0 |
       +|   (20% off of every after the 15th)            |     -2.0 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    49.80 |
       +| TOTAL                                          |     49.8 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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)>'

  4) 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                   10 |     10.0 |\n| Coupon TEA-TIME - 20% off                      |    -2.0 |\n+------------------------------------------------+----------+\n| TOTAL                                          |      8.0 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,9 +1,9 @@
        +------------------------------------------------+----------+
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
       -| Green Tea                                   10 |    10.00 |
       -| Coupon TEA-TIME - 20% off                      |    -2.00 |
       +| Green Tea                                   10 |     10.0 |
       +| Coupon TEA-TIME - 20% off                      |    -2.0 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |     8.00 |
       +| TOTAL                                          |      8.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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)>'

  5) 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:acee1f4,'0.0',4(8)>
            got: #<BigDecimal:acee230,'-0.2E1',4(12)>
       
       (compared using ==)
     # /tmp/d20111115-5847-vb2un7/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)>'

  6) 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: "+------------------------------------------------+----------+\n| Name                                       qty |    price |\n+------------------------------------------------+----------+\n| Green Tea                                    5 |      5.0 |\n| Coupon TEA-TIME - 0.1E2 off                    |   -10.0 |\n+------------------------------------------------+----------+\n| TOTAL                                          |     -5.0 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,9 +1,9 @@
        +------------------------------------------------+----------+
        | Name                                       qty |    price |
        +------------------------------------------------+----------+
       -| Green Tea                                    5 |     5.00 |
       -| Coupon TEA-TIME - 10.00 off                    |    -5.00 |
       +| Green Tea                                    5 |      5.0 |
       +| Coupon TEA-TIME - 0.1E2 off                    |   -10.0 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |     0.00 |
       +| TOTAL                                          |     -5.0 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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)>'

  7) 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: "+------------------------------------------------+----------+\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.9 |\n+------------------------------------------------+----------+\n| TOTAL                                          |    35.15 |\n+------------------------------------------------+----------+\n"
       
       (compared using ==)
       
       Diff:
       
       @@ -8,8 +8,8 @@
        | Milk                                         5 |     8.95 |
        |   (30% off of every after the 3rd)             |    -1.07 |
        | Cereal                                       3 |     7.47 |
       -| Coupon BREAKFAST - 10% off                     |    -3.91 |
       +| Coupon BREAKFAST - 10% off                     |    -3.9 |
        +------------------------------------------------+----------+
       -| TOTAL                                          |    35.16 |
       +| TOTAL                                          |    35.15 |
        +------------------------------------------------+----------+
     # /tmp/d20111115-5847-vb2un7/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.56994 seconds
19 examples, 7 failures

Failed examples:

rspec /tmp/d20111115-5847-vb2un7/spec.rb:104 # Inventory with a 'buy X, get one free' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-vb2un7/spec.rb:147 # Inventory with a '% off for every n' promotion shows the discount in the invoice
rspec /tmp/d20111115-5847-vb2un7/spec.rb:190 # Inventory with a '% off of every item after the nth' promotion shows the discount in the ivnoice
rspec /tmp/d20111115-5847-vb2un7/spec.rb:233 # Inventory with a '% off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-vb2un7/spec.rb:264 # Inventory with an 'amount off' coupon does not result in a negative total
rspec /tmp/d20111115-5847-vb2un7/spec.rb:274 # Inventory with an 'amount off' coupon shows the discount in the invoice
rspec /tmp/d20111115-5847-vb2un7/spec.rb:295 # Inventory with multiple discounts can print an invoice

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

Мая обнови решението на 07.11.2011 13:51 (преди около 13 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Cart
+ def initialize(products, promos, coupons)
+ @order = Hash.new(0)
+ @products = products
+ @promos = promos
+ @coupons = coupons
+ end
+
+ def add(name, quantity = 1)
+ if !@products.has_key? name or !(@order[name] + quantity).between?(1, 99)
+ raise "Invalid parameters passed."
+ end
+ @order[name] += quantity
+ end
+
+ def raw_total
+ price_total = 0
+ @order.map { |name, quantity| price_total +=
+ @promos[name].total(quantity, @products[name].to_d) }
+ price_total
+ end
+
+ def total
+ raw_total + (@used_coupon ? @used_coupon.discount(raw_total) : 0)
+ end
+
+ def invoice
+ @@line + @@header + @@line +
+ (@order.keys.map { |v| entry_to_s v }.inject("") { |s1, s2| s1 + s2 }) +
+ (@used_coupon ? @used_coupon.coupon_to_s(raw_total) : "") +
+ @@line + footer + @@line
+ end
+
+ def use(name)
+ @used_coupon = Coupon.new(name, @coupons[name])
+ end
+
+ @@line = "+------------------------------------------------+----------+\n"
+ @@header = "| Name qty | price |\n"
+
+ def raw_price(name)
+ @products[name].to_d * @order[name]
+ end
+
+ def footer
+ "| TOTAL | " +
+ total.truncate(2).to_s('F').rjust(8) + " |\n"
+ end
+
+ def entry_to_s(name)
+ "| " + name + @order[name].to_s.rjust(46 - name.length) + " | " +
+ raw_price(name).truncate(2).to_s('F').rjust(8) + " |\n" +
+ @promos[name].promo_to_s(@order[name], @products[name].to_d)
+ end
+end
+
+class Coupon
+ def initialize(name, spec)
+ @name = name
+ if spec.keys[0] == :percent
+ @percent = spec.values[0]
+ elsif spec.keys[0] == :amount
+ @amount = spec.values[0]
+ end
+ end
+
+ def coupon_to_s(price)
+ ("| Coupon " + @name + " - " + discount_to_s + " off").ljust(48) +
+ " |" + discount(price).truncate(2).to_s('F').rjust(8) + " |\n"
+ end
+
+ def discount_to_s
+ if @percent
+ @percent.to_s + "%"
+ elsif @amount
+ @amount.to_s
+ else
+ ""
+ end
+ end
+
+ def discount(price)
+ if @percent
+ -price * @percent / BigDecimal("100.0")
+ elsif @amount
+ -(@amount.to_d)
+ else
+ 0
+ end
+ end
+end
+
+class Promo
+ def total(quantity, price)
+ quantity * price + discount(quantity, price)
+ end
+
+ def promo_to_s(quantity, price)
+ ""
+ end
+end
+
+class StandardPrice < Promo
+ def discount(quantity, price)
+ 0
+ end
+end
+
+class GetOneFree < Promo
+ def initialize(count)
+ @count = count
+ end
+
+ def discount(quantity, price)
+ -(quantity / @count) * price
+ end
+
+ def promo_to_s(quantity, price)
+ ("| (buy " + (count - 1).to_s + ", get 1 free)").ljust(48) + " | " +
+ discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
+ end
+
+ attr_reader :count
+end
+
+class Package < Promo
+ def initialize(spec)
+ @count = spec.keys[0]
+ @percent = spec.values[0]
+ end
+
+ def discount(quantity, price)
+ -((quantity / @count) * @count * @percent * price) / BigDecimal("100.0")
+ end
+
+ def promo_to_s(quantity, price)
+ ("| (get " + @percent.to_s + "% off for every " + @count.to_s + ")").ljust(48) +
+ " | " + discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
+ end
+
+ attr_reader :count, :percent
+end
+
+class Threshold < Promo
+ def initialize(spec)
+ @count = spec.keys[0]
+ @percent = spec.values[0]
+ end
+
+ def discount(quantity, price)
+ if quantity <= count
+ return BigDecimal.new("0")
+ end
+
+ -((quantity - count) * price * @percent) / BigDecimal("100.0")
+ end
+
+ def promo_to_s(quantity, price)
+ descr = "% off of every after the "
+ ("| (" + @percent.to_s + descr + count_to_s + ")").ljust(48) +
+ " | " + discount(quantity, price).truncate(2).to_s('F').rjust(8) + " |\n"
+ end
+
+ def count_to_s
+ if count == 1
+ "1st"
+ elsif count == 2
+ "2nd"
+ elsif count == 3
+ "3rd"
+ else
+ @count.to_s + "th"
+ end
+ end
+
+ attr_reader :count, :percent
+end
+
+class Inventory
+ def initialize()
+ @products = {}
+ @promos = {}
+ @coupons = {}
+ end
+
+ def register(name, price, promo = {})
+ if name.length > 40 or !price.to_d.between?(0.01, 999.99) or @products.has_key? name
+ raise "Invalid parameters passed."
+ end
+
+ @products[name] = price
+
+ handle_promos promo, name
+ end
+
+ def handle_promos(promo, name)
+ if promo.has_key? :get_one_free
+ @promos[name] = GetOneFree.new(promo[:get_one_free])
+ elsif promo.has_key? :package
+ @promos[name] = Package.new(promo[:package])
+ elsif promo.has_key? :threshold
+ @promos[name] = Threshold.new(promo[:threshold])
+ else
+ @promos[name] = StandardPrice.new
+ end
+ end
+
+ def register_coupon(name, spec)
+ @coupons[name] = spec
+ end
+
+ def new_cart
+ return Cart.new(@products, @promos, @coupons)
+ end
+
+end