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

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

Към профила на Красимир Кирилов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 19 успешни тест(а)
  • 0 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Product
attr_accessor :name, :price, :promotion, :promotion_name
def initialize(new_name, new_price, new_promotion)
@name = new_name
@price = new_price.to_d
@promotion = Promotion.new(new_promotion)
@promotion_name = new_promotion.keys[0]
end
def use_promotion(amount)
case @promotion_name
when :get_one_free
@promotion.promotion_gof(amount)
when :package
@promotion.promotion_pac(amount)
when :threshold
@promotion.promotion_thres(amount)
else 0
end
end
def print_promotion(amount)
case @promotion_name
when :get_one_free
@promotion.print_gof(@price,amount)
when :package
@promotion.print_pac(@price)
when :threshold
@promotion.print_thres(@price,amount)
else ""
end
end
def get_promotion()
@promotion.amount_promotion
end
end
class Inventory
attr_accessor :inventory, :coupons
def initialize
@inventory = []
@coupons = []
end
def register (product_name, product_price, promotion = {})
parameters_check(product_name, product_price)
@inventory << Product.new(product_name, product_price, promotion)
end
def new_cart ()
Cart.new(@inventory, @coupons)
end
def search_product(name)
@inventory.select {|product| product.name == name}
end
def parameters_check (name, price)
price = price.to_d
if name.length > 40
raise ArgumentError.new("Bad argument name")
end
if price>999.99 || price <0.01
raise ArgumentError.new("Bad argument price")
end
@inventory.each do |product|
if product.name == name
raise ArgumentError.new("Product already exist")
end
end
end
def register_coupon (name,function)
if (function.keys[0] == :amount) then function.values[0] = function.values[0].to_d
end
coupon_check(name,function)
@coupons<<Coupon.new(name,function)
end
def coupon_check(name,function)
@coupons.each do |coupon|
if coupon.name == name
raise ArgumentError("Already have that coupon")
end
end
if function.keys[0] =! :amount || function.keys[0] =! :percent
raise ArgumentError("There is no coupon with that function")
end
if "#{function.values[0]}".to_d <= 0
raise ArgumentError("The coupon values must be >0")
end
end
end
class Cart
Sep = "+------------------------------------------------+----------+\n"
Top = "| Name qty | price |\n"
attr_accessor :cart, :total, :inventory, :coupon_flag, :used_coupon, :coupons
def initialize(new_inventory, new_coupons)
@used_coupon = Coupon.new("default",{})
@cart = {}
@total = "0.0".to_d
@inventory = new_inventory
@coupons = new_coupons
@coupon_flag = false
end
def total
if (@coupon_flag) then @total = @used_coupon.use(@total)
else @total
end
end
def search_product(name)
@inventory.select {|product| product.name == name}
end
def add (product_name, amount = 1)
amount_check(amount)
product = search_product(product_name)[0]
if has_product?(product_name)
@cart[product] = @cart[product] + amount
else
@cart[product] = amount
end
@total += amount*product.price - product.use_promotion(cart[product])*product.price
end
def amount_check(amount)
if amount < 1 then raise ArgumentError("The amount of the product must be > 1")
end
if amount != amount.to_i then raise ArgumentError("The amount must be integer")
end
end
def has_product?(name)
@cart.each do |key,value|
if key.name == name
return true
end
end
false
end
def use(name)
@used_coupon = search_coupon(name)
coupon_used()
end
def coupon_used()
if (@coupon_flag)
raise ("Already use coupon in this cart")
end
@coupon_flag = true
end
def search_coupon(name)
@coupons.select {|coupon| coupon.name == name}[0]
end
def invoice
line = ""
if (coupon_flag) then @total = @used_coupon.use(@total)
end
@cart.each do |key,value|
line = line + "| #{key.name.ljust(33)}#{value.to_s.rjust(13)} |"
line = line + "#{sprintf('%.2f',key.price*value).rjust(9)} |\n"
line = line + key.print_promotion(value)
end
down = "| TOTAL".ljust(49)+"|#{sprintf('%.2f',@total).rjust(9)} |\n"
Sep + Top + Sep + line + @used_coupon.print_coupon + Sep + down + Sep
end
end
class Promotion
attr_accessor :promotion_hash, :amount_promotion, :check_pr
def initialize(new_promotion)
@amount_promotion = 0
@check_pr = 0
@promotion_hash = new_promotion
if @promotion_hash.length > 1 then raise ArgumentError("Can have only 1 promotion")
end
end
def use_promotion(amount)
case @promotion_hash.keys[0]
when :get_one_free
promotion_gof(@promotion_hash,amount)
when :package
promotion_pac(@promotion_hash,amount)
when :threshold
promotion_tres(@promotion_hash,amount)
else
end
end
def promotion_gof(amount)
@amount_promotion = amount/@promotion_hash.values[0]
@amount_promotion
end
def promotion_pac(amount)
promotion_value = @promotion_hash.values[0].values[0]
@check_pr
@amount_promotion = amount - amount % @promotion_hash.values[0].keys[0]
@amount_promotion = "#{@amount_promotion}".to_d
@amount_promotion = @amount_promotion * promotion_value/100 - check_pr
@check_pr = @amount_promotion + @check_pr
@amount_promotion
end
def promotion_thres(amount)
if amount<=@promotion_hash.values[0].keys[0]
return 0
else
@amount_promotion = amount - @check_pr - @promotion_hash.values[0].keys[0]
@check_pr = @check_pr + @amount_promotion
end
@amount_promotion = "#{@amount_promotion}".to_d
@amount_promotion = @amount_promotion * @promotion_hash.values[0].values[0]/100
end
def print_gof(price,amount)
price = price * amount_promotion
price = price.to_f
promotion_line = "| (buy #{promotion_hash.values[0]-1}, get 1 free)".ljust(49)
promotion_line = promotion_line + "|#{sprintf('%.2f',(-price)).to_s.rjust(9)} |\n"
check_pr = 0
promotion_line
end
def print_pac(price)
price = @check_pr * price
price = price.to_f
line = "| (get #{@promotion_hash.values[0].values[0]}% off for every "
line = line + "#{@promotion_hash.values[0].keys[0]})".ljust(22)
line = line + "|#{sprintf('%.2f',-price).rjust(9)} |\n"
@check_pr = 0
line
end
def print_thres(price,amount)
pr_value = price*@check_pr*@promotion_hash.values[0].values[0]/100
suff = suffix()
line = "| (#{@promotion_hash.values[0].values[0]}% off of every after the"
line = line + " #{@promotion_hash.values[0].keys[0].to_s+suff})".ljust(18)
line = line + "|#{sprintf('%.2f',-pr_value).rjust(9)} |\n"
@check_pr = 0
line
end
def suffix()
case @promotion_hash.values[0].keys[0]
when 1
return "st"
when 2
return "nd"
when 3
return "rd"
end
return "th"
end
end
class Coupon
attr_accessor :name, :function, :discount, :coupon_flag
def initialize(new_name,new_function)
@discount = "0.00".to_d
@name = new_name
@function = new_function
@coupon_flag = false
end
def use(total)
@coupon_flag = true
if @function.keys[0] == :percent
use_percent(total)
else
use_amount(total)
end
end
def use_percent(total)
@discount = @discount + total * @function.values[0]/100
total = total - total * @function.values[0]/100
if total < 0 then 0
else total
end
end
def use_amount(total)
@discount = @discount + function.values[0].to_d
if @discount > total then @discount = total
end
total = total - function.values[0].to_d
if total < 0 then 0
else total
end
end
def print_coupon
if @coupon_flag
@coupon_flag = false
coupon_roll
else
""
end
end
def coupon_roll
if (@function.keys[0] == :percent)
coupon ="| Coupon #{@name} - #{@function.values[0]}% off".ljust(49)
coupon = coupon + "|#{sprintf('%.2f',-(@discount)).rjust(9)} |\n"
else
coupon = "| Coupon #{@name} - ".ljust(20)
coupon = coupon + "#{sprintf('%.2f',@function.values[0])} off".ljust(29)
coupon = coupon + "|#{sprintf('%.2f',-(@discount)).rjust(9)} |\n"
end
end
end

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

...................

Finished in 0.56792 seconds
19 examples, 0 failures

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

Красимир обнови решението на 07.11.2011 16:35 (преди над 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Product
+
+ attr_accessor :name, :price, :promotion, :promotion_name
+
+ def initialize(new_name, new_price, new_promotion)
+ @name = new_name
+ @price = new_price.to_d
+ @promotion = Promotion.new(new_promotion)
+ @promotion_name = new_promotion.keys[0]
+ end
+
+ def use_promotion(amount)
+ case @promotion_name
+ when :get_one_free
+ @promotion.promotion_gof(amount)
+ when :package
+ @promotion.promotion_pac(amount)
+ when :threshold
+ @promotion.promotion_thres(amount)
+ else 0
+ end
+ end
+
+ def print_promotion(amount)
+ case @promotion_name
+ when :get_one_free
+ @promotion.print_gof(@price,amount)
+ when :package
+ @promotion.print_pac(@price)
+ when :threshold
+ @promotion.print_thres(@price,amount)
+ else ""
+ end
+ end
+
+ def get_promotion()
+ @promotion.amount_promotion
+ end
+
+end
+
+
+class Inventory
+
+ attr_accessor :inventory, :coupons
+
+ def initialize
+ @inventory = []
+ @coupons = []
+ end
+
+ def register (product_name, product_price, promotion = {})
+ parameters_check(product_name, product_price)
+ @inventory << Product.new(product_name, product_price, promotion)
+ end
+
+ def new_cart ()
+ Cart.new(@inventory, @coupons)
+ end
+
+ def search_product(name)
+ @inventory.select {|product| product.name == name}
+ end
+
+ def parameters_check (name, price)
+ price = price.to_d
+ if name.length > 40
+ raise ArgumentError.new("Bad argument name")
+ end
+ if price>999.99 || price <0.01
+ raise ArgumentError.new("Bad argument price")
+ end
+ @inventory.each do |product|
+ if product.name == name
+ raise ArgumentError.new("Product already exist")
+ end
+ end
+ end
+
+ def register_coupon (name,function)
+ if (function.keys[0] == :amount) then function.values[0] = function.values[0].to_d
+ end
+ coupon_check(name,function)
+ @coupons<<Coupon.new(name,function)
+ end
+
+ def coupon_check(name,function)
+ @coupons.each do |coupon|
+ if coupon.name == name
+ raise ArgumentError("Already have that coupon")
+ end
+ end
+ if function.keys[0] =! :amount || function.keys[0] =! :percent
+ raise ArgumentError("There is no coupon with that function")
+ end
+
+ if "#{function.values[0]}".to_d <= 0
+ raise ArgumentError("The coupon values must be >0")
+ end
+ end
+
+end
+
+class Cart
+
+
+ Sep = "+------------------------------------------------+----------+\n"
+ Top = "| Name qty | price |\n"
+
+ attr_accessor :cart, :total, :inventory, :coupon_flag, :used_coupon, :coupons
+
+ def initialize(new_inventory, new_coupons)
+ @used_coupon = Coupon.new("default",{})
+ @cart = {}
+ @total = "0.0".to_d
+ @inventory = new_inventory
+ @coupons = new_coupons
+ @coupon_flag = false
+ end
+
+ def total
+ if (@coupon_flag) then @total = @used_coupon.use(@total)
+ else @total
+ end
+ end
+
+ def search_product(name)
+ @inventory.select {|product| product.name == name}
+ end
+
+ def add (product_name, amount = 1)
+ amount_check(amount)
+ product = search_product(product_name)[0]
+ if has_product?(product_name)
+ @cart[product] = @cart[product] + amount
+ else
+ @cart[product] = amount
+ end
+ @total += amount*product.price - product.use_promotion(cart[product])*product.price
+ end
+
+ def amount_check(amount)
+ if amount < 1 then raise ArgumentError("The amount of the product must be > 1")
+ end
+ if amount != amount.to_i then raise ArgumentError("The amount must be integer")
+ end
+ end
+
+ def has_product?(name)
+ @cart.each do |key,value|
+ if key.name == name
+ return true
+ end
+ end
+ false
+ end
+
+ def use(name)
+ @used_coupon = search_coupon(name)
+ coupon_used()
+ end
+
+ def coupon_used()
+ if (@coupon_flag)
+ raise ("Already use coupon in this cart")
+ end
+ @coupon_flag = true
+ end
+
+ def search_coupon(name)
+ @coupons.select {|coupon| coupon.name == name}[0]
+ end
+
+ def invoice
+ line = ""
+ if (coupon_flag) then @total = @used_coupon.use(@total)
+ end
+ @cart.each do |key,value|
+ line = line + "| #{key.name.ljust(33)}#{value.to_s.rjust(13)} |"
+ line = line + "#{sprintf('%.2f',key.price*value).rjust(9)} |\n"
+ line = line + key.print_promotion(value)
+ end
+ down = "| TOTAL".ljust(49)+"|#{sprintf('%.2f',@total).rjust(9)} |\n"
+ Sep + Top + Sep + line + @used_coupon.print_coupon + Sep + down + Sep
+ end
+end
+
+class Promotion
+
+ attr_accessor :promotion_hash, :amount_promotion, :check_pr
+
+ def initialize(new_promotion)
+ @amount_promotion = 0
+ @check_pr = 0
+ @promotion_hash = new_promotion
+ if @promotion_hash.length > 1 then raise ArgumentError("Can have only 1 promotion")
+ end
+ end
+
+ def use_promotion(amount)
+ case @promotion_hash.keys[0]
+ when :get_one_free
+ promotion_gof(@promotion_hash,amount)
+ when :package
+ promotion_pac(@promotion_hash,amount)
+ when :threshold
+ promotion_tres(@promotion_hash,amount)
+ else
+ end
+ end
+
+ def promotion_gof(amount)
+ @amount_promotion = amount/@promotion_hash.values[0]
+ @amount_promotion
+ end
+
+ def promotion_pac(amount)
+ promotion_value = @promotion_hash.values[0].values[0]
+ @check_pr
+ @amount_promotion = amount - amount % @promotion_hash.values[0].keys[0]
+ @amount_promotion = "#{@amount_promotion}".to_d
+ @amount_promotion = @amount_promotion * promotion_value/100 - check_pr
+ @check_pr = @amount_promotion + @check_pr
+ @amount_promotion
+ end
+
+ def promotion_thres(amount)
+ if amount<=@promotion_hash.values[0].keys[0]
+ return 0
+ else
+ @amount_promotion = amount - @check_pr - @promotion_hash.values[0].keys[0]
+ @check_pr = @check_pr + @amount_promotion
+ end
+ @amount_promotion = "#{@amount_promotion}".to_d
+ @amount_promotion = @amount_promotion * @promotion_hash.values[0].values[0]/100
+ end
+
+ def print_gof(price,amount)
+ price = price * amount_promotion
+ price = price.to_f
+ promotion_line = "| (buy #{promotion_hash.values[0]-1}, get 1 free)".ljust(49)
+ promotion_line = promotion_line + "|#{sprintf('%.2f',(-price)).to_s.rjust(9)} |\n"
+ check_pr = 0
+ promotion_line
+ end
+
+ def print_pac(price)
+ price = @check_pr * price
+ price = price.to_f
+ line = "| (get #{@promotion_hash.values[0].values[0]}% off for every "
+ line = line + "#{@promotion_hash.values[0].keys[0]})".ljust(22)
+ line = line + "|#{sprintf('%.2f',-price).rjust(9)} |\n"
+ @check_pr = 0
+ line
+ end
+
+ def print_thres(price,amount)
+ pr_value = price*@check_pr*@promotion_hash.values[0].values[0]/100
+ suff = suffix()
+ line = "| (#{@promotion_hash.values[0].values[0]}% off of every after the"
+ line = line + " #{@promotion_hash.values[0].keys[0].to_s+suff})".ljust(18)
+ line = line + "|#{sprintf('%.2f',-pr_value).rjust(9)} |\n"
+ @check_pr = 0
+ line
+ end
+
+ def suffix()
+ case @promotion_hash.values[0].keys[0]
+ when 1
+ return "st"
+ when 2
+ return "nd"
+ when 3
+ return "rd"
+ end
+ return "th"
+ end
+
+end
+
+class Coupon
+
+ attr_accessor :name, :function, :discount, :coupon_flag
+
+ def initialize(new_name,new_function)
+ @discount = "0.00".to_d
+ @name = new_name
+ @function = new_function
+ @coupon_flag = false
+ end
+
+ def use(total)
+ @coupon_flag = true
+ if @function.keys[0] == :percent
+ use_percent(total)
+ else
+ use_amount(total)
+ end
+ end
+
+ def use_percent(total)
+ @discount = @discount + total * @function.values[0]/100
+ total = total - total * @function.values[0]/100
+ if total < 0 then 0
+ else total
+ end
+ end
+
+ def use_amount(total)
+ @discount = @discount + function.values[0].to_d
+ if @discount > total then @discount = total
+ end
+ total = total - function.values[0].to_d
+ if total < 0 then 0
+ else total
+ end
+ end
+
+ def print_coupon
+ if @coupon_flag
+ @coupon_flag = false
+ coupon_roll
+ else
+ ""
+ end
+ end
+
+ def coupon_roll
+ if (@function.keys[0] == :percent)
+ coupon ="| Coupon #{@name} - #{@function.values[0]}% off".ljust(49)
+ coupon = coupon + "|#{sprintf('%.2f',-(@discount)).rjust(9)} |\n"
+ else
+ coupon = "| Coupon #{@name} - ".ljust(20)
+ coupon = coupon + "#{sprintf('%.2f',@function.values[0])} off".ljust(29)
+ coupon = coupon + "|#{sprintf('%.2f',-(@discount)).rjust(9)} |\n"
+ end
+ end
+end