Решение на Трета задача от Михаил Петков

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

Към профила на Михаил Петков

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Inventory
Min = BigDecimal('0.01')
Max = BigDecimal('999.99')
attr_accessor :products, :coupons
def initialize()
@products = []
@coupons = {}
end
def register(product, product_cost, promotion = "no")
cost = product_cost.to_d
if(product.length() > 40 || cost < Min || cost > Max || products.include?(product))
raise "Invalid parameters passed."
else
@products << product << product_cost << promotion
end
end
def new_cart()
cart = Cart.new(@products, @coupons)
end
def register_coupon(name, type)
@coupons[name] = type
end
end
class Cart
attr_accessor :sum, :counter, :basket, :products, :coupons, :invoice
BottomLeft = "| TOTAL "+" ".ljust(41) + "| ".ljust(5)
Row = "+".ljust(49,"-") + "+".ljust(11,"-")+"+\n"
def initialize(*params)
@counter = 0
@sum = 0
@basket = {}
@products = params[0]
@coupons = params[1]
@invoice = ""
end
def add(added_product, quantity = 1)
raise "Invalid parameters passed." if !@products.include?(added_product)
raise "Invalid parameters passed." if (quantity <= 0 || quantity > 99)
if @basket.has_key?(added_product)
@basket[added_product] = @basket[added_product] + quantity
else
@basket[added_product] = quantity
end
raise "Invalid parameters passed." if @basket[added_product] > 99
check_promotions(added_product)
end
def check_promotions(added_product)
products.each_slice(3) do |item|
if(item[2] != "no" && item[0] == added_product)
hash_keys = item[2].keys
hash_values = item[2].values
add_promotion(added_product, hash_keys[0], hash_values[0])
end
end
end
def add_promotion(added_product, key, value)
promotions = Promotions.new(@products, @basket)
promotions.get_one_free(added_product, value) if key.to_s == "get_one_free"
promotions.package(added_product, value) if key.to_s == "package"
promotions.threshold(added_product, value) if key.to_s == "threshold"
end
def count_sume()
@sum = 0
basket.each() do |product, quantity|
if products.include?(product)
price = get_price(product)
@sum = @sum + quantity * price.to_d
else
price = basket[product]
@sum = @sum - price
end
end
end
def get_price(product)
product_price = nil
products.each_slice(3) do |item|
product_price = item[1] if item[0] == product
end
product_price
end
def total()
count_sume()
final_result = @sum
final_result = 0 if @sum < 0
final_result
end
def use(name)
count_sume()
coupon = Coupons.new(@basket, @coupons)
@counter = @counter + 1
@sum = coupon.total(name, @sum) if coupons.has_key?(name) && @counter == 1
@sum = sprintf("%.2f", @sum)
end
def invoice()
count_sume()
@invoice = Row + "| Name" + " ".rjust(39) + "qty | price |\n" + Row
@basket.each do |key, quantity|
res = get_price(key).to_d * quantity if @products.include?(key)
res = @basket[key] if !@products.include?(key)
put_lines(quantity, key, res)
end
@sum = 0 if @sum < 0.01
@invoice += Row + BottomLeft + sprintf("%.2f",@sum).rjust(5)+" |\n"+ Row
end
def put_lines(quantity, key, res)
quantity = sprintf("%.0f", quantity)
if @products.include?(key)
right_line = " | ".ljust(6) + sprintf("%.2f",res).rjust(5) + " |\n"
@invoice += "| " + key.ljust(42) + quantity.rjust(4) + right_line
else
@invoice += "| " + key.ljust(46) + " | ".ljust(5)
@invoice += sprintf("%.2f",-res).rjust(6) + " |\n"
end
end
end
class Promotions
attr_accessor :basket, :products
def initialize(*params)
@products = params[0]
@basket = params[1]
end
def get_one_free(product, value)
quantity = @basket[product] / value
get_product_price(product)
discount = @price * quantity
string = " (buy "+sprintf("%.0f",value-1)+", get 1 free)"
@basket[string] = discount
end
def package(product, hash)
hash.each { |key, value| @count = key, @percent = value }
get_product_price(product)
counter = @basket[product] / @count[0]
left = @basket[product] % @count[0]
cut = @price * counter * @count[0] * (100 - @percent) / 100 + @price * left
@discount = @price * @basket[product] - cut
@basket[package_message()] = @discount if @basket[product] >= @count[0]
end
def threshold(product, hash)
hash.each { |key, value| @count = key, @percent = value }
get_product_price(product)
counter = @basket[product] - @count[0]
cut = counter * @price * (100 - @percent) / 100 + @count[0] * @price
@discount = @basket[product] * @price - cut
@basket[threshold_message()] = @discount if counter > 0
end
def get_product_price(product)
@products.each_slice(3) do |item|
@price = item[1].to_d if item[0] == product
end
end
def package_message()
left = " (get "+sprintf("%.0f",@percent)
right = "% off for every " + sprintf("%.0f",@count[0])+")"
message = left + right
end
def threshold_message()
left = " ("+sprintf("%.0f",@percent)
middle = "% off of every after the "
number_end = get_end(@count[0])
right = sprintf("%.0f",@count[0])+number_end+")"
message = left + middle + right
end
def get_end(number)
last_digit = number % 10
result = "st" if last_digit == 1
result = "nd" if last_digit == 2
result = "rd" if last_digit == 3
result = "th" if last_digit != 1 && last_digit != 2 && last_digit != 3
result
end
end
class Coupons
attr_accessor :basket, :coupons
def initialize(*params)
@basket = params[0]
@coupons = params[1]
end
def percent_coupon(total, value)
result = total * value / 100
end
def total(used, total)
coupons[used].each { |key, result| @type = key.to_s, @value = result }
@value = @value.to_d if @type[0] == "amount"
coupon = percent_coupon(total, @value) if @type[0] == "percent"
coupon = @value if @type[0] == "amount"
coupon_value(coupon,total,used,'%') if @type[0] == "percent"
coupon_value(coupon,total,used,'') if @type[0] == "amount"
total = total - sprintf("%.2f", coupon).to_d
end
def coupon_value(coupon,total,used,percent)
if coupon > total && total > BigDecimal('0.00')
@basket[message(used,percent)] = total
else
@basket[message(used,percent)] = coupon
end
end
def message(used,percent)
if percent == "%"
message = "Coupon "+ used + " - " + sprintf("%.0f",@value) + percent + " off"
else
message = "Coupon "+ used + " - " + sprintf("%.2f",@value) + percent + " off"
end
end
end

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

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

Finished in 0.56401 seconds
19 examples, 0 failures

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

Михаил обнови решението на 06.11.2011 19:20 (преди около 13 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Inventory
+ Min = BigDecimal('0.01')
+ Max = BigDecimal('999.99')
+ attr_accessor :products, :coupons
+
+ def initialize()
+ @products = []
+ @coupons = {}
+ end
+
+ def register(product, product_cost, promotion = "no")
+ cost = product_cost.to_d
+ if(product.length() > 40 || cost < Min || cost > Max || products.include?(product))
+ raise "Invalid parameters passed."
+ else
+ @products << product << product_cost << promotion
+ end
+ end
+
+ def new_cart()
+ cart = Cart.new(@products, @coupons)
+ end
+
+ def register_coupon(name, type)
+ @coupons[name] = type
+ end
+end
+
+class Cart
+ attr_accessor :sum, :counter, :basket, :products, :coupons, :invoice
+ BottomLeft = "| TOTAL "+" ".ljust(41) + "| ".ljust(5)
+ Row = "+".ljust(49,"-") + "+".ljust(11,"-")+"+\n"
+
+ def initialize(*params)
+ @counter = 0
+ @sum = 0
+ @basket = {}
+ @products = params[0]
+ @coupons = params[1]
+ @invoice = ""
+ end
+
+ def add(added_product, quantity = 1)
+ raise "Invalid parameters passed." if !@products.include?(added_product)
+ raise "Invalid parameters passed." if (quantity <= 0 || quantity > 99)
+ if @basket.has_key?(added_product)
+ @basket[added_product] = @basket[added_product] + quantity
+ else
+ @basket[added_product] = quantity
+ end
+ raise "Invalid parameters passed." if @basket[added_product] > 99
+ check_promotions(added_product)
+ end
+
+ def check_promotions(added_product)
+ products.each_slice(3) do |item|
+ if(item[2] != "no" && item[0] == added_product)
+ hash_keys = item[2].keys
+ hash_values = item[2].values
+ add_promotion(added_product, hash_keys[0], hash_values[0])
+ end
+ end
+ end
+
+ def add_promotion(added_product, key, value)
+ promotions = Promotions.new(@products, @basket)
+ promotions.get_one_free(added_product, value) if key.to_s == "get_one_free"
+ promotions.package(added_product, value) if key.to_s == "package"
+ promotions.threshold(added_product, value) if key.to_s == "threshold"
+ end
+
+ def count_sume()
+ @sum = 0
+ basket.each() do |product, quantity|
+ if products.include?(product)
+ price = get_price(product)
+ @sum = @sum + quantity * price.to_d
+ else
+ price = basket[product]
+ @sum = @sum - price
+ end
+ end
+ end
+
+ def get_price(product)
+ product_price = nil
+ products.each_slice(3) do |item|
+ product_price = item[1] if item[0] == product
+ end
+ product_price
+ end
+
+ def total()
+ count_sume()
+ final_result = @sum
+ final_result = 0 if @sum < 0
+ final_result
+ end
+
+ def use(name)
+ count_sume()
+ coupon = Coupons.new(@basket, @coupons)
+ @counter = @counter + 1
+ @sum = coupon.total(name, @sum) if coupons.has_key?(name) && @counter == 1
+ @sum = sprintf("%.2f", @sum)
+ end
+
+ def invoice()
+ count_sume()
+ @invoice = Row + "| Name" + " ".rjust(39) + "qty | price |\n" + Row
+ @basket.each do |key, quantity|
+ res = get_price(key).to_d * quantity if @products.include?(key)
+ res = @basket[key] if !@products.include?(key)
+ put_lines(quantity, key, res)
+ end
+ @sum = 0 if @sum < 0.01
+ @invoice += Row + BottomLeft + sprintf("%.2f",@sum).rjust(5)+" |\n"+ Row
+ end
+
+ def put_lines(quantity, key, res)
+ quantity = sprintf("%.0f", quantity)
+ if @products.include?(key)
+ right_line = " | ".ljust(6) + sprintf("%.2f",res).rjust(5) + " |\n"
+ @invoice += "| " + key.ljust(42) + quantity.rjust(4) + right_line
+ else
+ @invoice += "| " + key.ljust(46) + " | ".ljust(5)
+ @invoice += sprintf("%.2f",-res).rjust(6) + " |\n"
+ end
+ end
+end
+
+class Promotions
+ attr_accessor :basket, :products
+
+ def initialize(*params)
+ @products = params[0]
+ @basket = params[1]
+ end
+
+ def get_one_free(product, value)
+ quantity = @basket[product] / value
+ get_product_price(product)
+ discount = @price * quantity
+ string = " (buy "+sprintf("%.0f",value-1)+", get 1 free)"
+ @basket[string] = discount
+ end
+
+ def package(product, hash)
+ hash.each { |key, value| @count = key, @percent = value }
+ get_product_price(product)
+ counter = @basket[product] / @count[0]
+ left = @basket[product] % @count[0]
+ cut = @price * counter * @count[0] * (100 - @percent) / 100 + @price * left
+ @discount = @price * @basket[product] - cut
+ @basket[package_message()] = @discount if @basket[product] >= @count[0]
+ end
+
+ def threshold(product, hash)
+ hash.each { |key, value| @count = key, @percent = value }
+ get_product_price(product)
+ counter = @basket[product] - @count[0]
+ cut = counter * @price * (100 - @percent) / 100 + @count[0] * @price
+ @discount = @basket[product] * @price - cut
+ @basket[threshold_message()] = @discount if counter > 0
+ end
+
+ def get_product_price(product)
+ @products.each_slice(3) do |item|
+ @price = item[1].to_d if item[0] == product
+ end
+ end
+
+ def package_message()
+ left = " (get "+sprintf("%.0f",@percent)
+ right = "% off for every " + sprintf("%.0f",@count[0])+")"
+ message = left + right
+ end
+
+ def threshold_message()
+ left = " ("+sprintf("%.0f",@percent)
+ middle = "% off of every after the "
+ number_end = get_end(@count[0])
+ right = sprintf("%.0f",@count[0])+number_end+")"
+ message = left + middle + right
+ end
+
+ def get_end(number)
+ last_digit = number % 10
+ result = "st" if last_digit == 1
+ result = "nd" if last_digit == 2
+ result = "rd" if last_digit == 3
+ result = "th" if last_digit != 1 && last_digit != 2 && last_digit != 3
+ result
+ end
+end
+
+class Coupons
+ attr_accessor :basket, :coupons
+
+ def initialize(*params)
+ @basket = params[0]
+ @coupons = params[1]
+ end
+
+ def percent_coupon(total, value)
+ result = total * value / 100
+ end
+
+ def total(used, total)
+ coupons[used].each { |key, result| @type = key.to_s, @value = result }
+ @value = @value.to_d if @type[0] == "amount"
+ coupon = percent_coupon(total, @value) if @type[0] == "percent"
+ coupon = @value if @type[0] == "amount"
+ coupon_value(coupon,total,used,'%') if @type[0] == "percent"
+ coupon_value(coupon,total,used,'') if @type[0] == "amount"
+ total = total - sprintf("%.2f", coupon).to_d
+ end
+
+ def coupon_value(coupon,total,used,percent)
+ if coupon > total && total > BigDecimal('0.00')
+ @basket[message(used,percent)] = total
+ else
+ @basket[message(used,percent)] = coupon
+ end
+ end
+
+ def message(used,percent)
+ if percent == "%"
+ message = "Coupon "+ used + " - " + sprintf("%.0f",@value) + percent + " off"
+ else
+ message = "Coupon "+ used + " - " + sprintf("%.2f",@value) + percent + " off"
+ end
+ end
+end