Решение на Трета задача от Елена Иванова

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

Към профила на Елена Иванова

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Inventory
def initialize()
@products = {}
@coupons = {}
end
def register(product_name, price, promotion = {})
price = price.to_d
verify_arguments product_name, price
promotion = parse_promotion(promotion)
product = Product.new product_name, price, promotion
@products[product_name] = product
end
def new_cart()
Cart.new self
end
def contains?(product_name)
@products[product_name] ? true : false
end
def get_product(product_name)
@products[product_name]
end
def register_coupon(name, description)
if description[:amount]
description[:amount] = description[:amount].to_d
end
@coupons[name] = description
end
def get_coupon(name)
Coupon.new name, @coupons[name]
end
private
def verify_arguments(product_name, price)
criteria = []
criteria << not(@products[product_name])
criteria << (product_name.length <= 40)
criteria << (price >= 0.01 and price <= 999.99)
valid = criteria.inject {|s, condition| s and condition}
raise "Invalid parameters passed." unless valid
end
def parse_promotion(hash)
if hash
promotion = GetOneFreePromotion.new hash[:get_one_free] if hash[:get_one_free]
promotion = PackagePromotion.new hash[:package] if hash[:package]
promotion = ThresholdPromotion.new hash[:threshold] if hash[:threshold]
end
promotion
end
end
class Cart
def initialize(inventory)
@cartProducts = Hash.new 0
@inventory = inventory
@coupon = nil
end
def add(product_name, number = 1)
verify_product product_name, number
product_to_add = @inventory.get_product product_name
@cartProducts[product_to_add] = @cartProducts[product_to_add] + number
end
def total_no_coupons()
curr_total = 0
@cartProducts.each { |product, count| curr_total += product.get_price(count)}
curr_total
end
def total()
curr_total = total_no_coupons
coupon_discount = coupon_discount curr_total
coupon_discount > curr_total ? curr_total = 0 : curr_total -= coupon_discount
curr_total
end
def coupon_discount(total)
if @coupon
coupon_discount = @coupon.details[:amount] if @coupon.details[:amount]
percent = @coupon.details[:percent]
coupon_discount = total * percent / 100 if percent
coupon_discount = total if coupon_discount > total
else coupon_discount = 0
end
coupon_discount
end
def invoice()
invoice_s = header
@cartProducts.each { |product, count| invoice_s << get_line(product, count)}
if @coupon
discount = -coupon_discount(total_no_coupons)
invoice_s << format("| %-46s |%9.2f |\n", @coupon.coupon_string, discount)
end
invoice_s << "+------------------------------------------------+----------+\n"
invoice_s << format("| %-46s |%9.2f |\n", "TOTAL", total)
invoice_s << "+------------------------------------------------+----------+\n"
end
def use(coupon_name)
@coupon = @inventory.get_coupon(coupon_name)
end
private
def header
invoice_s = "+------------------------------------------------+----------+\n"
invoice_s << "| Name qty | price |\n"
invoice_s << "+------------------------------------------------+----------+\n"
end
def verify_product(product_name, number)
is_existing = @inventory.contains? product_name
product_to_add = @inventory.get_product product_name
is_number_ok = (number > 0 and number <= 99)
is_number_ok = (is_number_ok and @cartProducts[product_to_add] + number <= 99)
unless is_existing and is_number_ok
raise "Invalid parameters passed."
end
end
def get_line(product, count)
format_s = "| %-44s%2d |%9.2f |\n"
line = format format_s, product.name, count, product.price * count
if product.promotion != nil
discount = -product.get_discount(count)
discount_string = product.get_discount_string(count)
line << format("| %-45s|%9.2f |\n", discount_string, discount)
end
line
end
end
class Product
attr_accessor :name, :price, :promotion
def initialize(name, price, promotion)
@name = name
@price = price
@promotion = promotion
end
def get_price(count)
if @promotion
price * count - get_discount(count)
else price * count
end
end
def get_discount(count)
@promotion.get_discount(self, count)
end
def get_discount_string(count)
if @promotion
@promotion.get_discount_string
end
end
end
class GetOneFreePromotion
def initialize(nth_free)
@nThFree = nth_free
end
def get_discount(product, count)
product.price * (count / @nThFree)
end
def get_discount_string
format "(buy %d, get 1 free)", @nThFree - 1
end
end
class PackagePromotion
def initialize(hash)
@packageSize = hash.keys[0]
@discount = hash.values[0]
end
def get_discount(product, count)
discount_count = count / @packageSize
discount_count * @packageSize * product.price * @discount / 100
end
def get_discount_string
format "(get %d%% off for every %d)", @discount, @packageSize
end
end
class ThresholdPromotion
def initialize(hash)
@fullPriceNum = hash.keys[0]
@discount = hash.values[0]
end
def get_discount(product, count)
discount_count = count > @fullPriceNum ? count - @fullPriceNum : 0
discount_count * product.price * @discount / 100
end
def get_discount_string
tail = case @fullPriceNum
when 1 then "st"
when 2 then "nd"
when 3 then "rd"
else "th"
end
format "(%d%% off of every after the %d%s)", @discount, @fullPriceNum, tail
end
end
class Coupon
attr_accessor :name, :details
def initialize(name, details)
@name = name
@details = details
end
def coupon_string
discount = if @details[:percent]
"#{@details[:percent]}%"
else format "%.2f", @details[:amount]
end
"Coupon #{@name} - #{discount} off"
end
end

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

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

Finished in 0.58399 seconds
19 examples, 0 failures

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

Елена обнови решението на 06.11.2011 23:16 (преди около 13 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Inventory
+
+ def initialize()
+ @products = {}
+ @coupons = {}
+ end
+
+ def register(product_name, price, promotion = {})
+ price = price.to_d
+ verify_arguments product_name, price
+ promotion = parse_promotion(promotion)
+ product = Product.new product_name, price, promotion
+ @products[product_name] = product
+ end
+
+ def new_cart()
+ Cart.new self
+ end
+
+ def contains?(product_name)
+ @products[product_name] ? true : false
+ end
+
+ def get_product(product_name)
+ @products[product_name]
+ end
+
+ def register_coupon(name, description)
+ if description[:amount]
+ description[:amount] = description[:amount].to_d
+ end
+ @coupons[name] = description
+ end
+
+ def get_coupon(name)
+ Coupon.new name, @coupons[name]
+ end
+
+ private
+
+ def verify_arguments(product_name, price)
+ criteria = []
+ criteria << not(@products[product_name])
+ criteria << (product_name.length <= 40)
+ criteria << (price >= 0.01 and price <= 999.99)
+ valid = criteria.inject {|s, condition| s and condition}
+ raise "Invalid parameters passed." unless valid
+ end
+
+ def parse_promotion(hash)
+ if hash
+ promotion = GetOneFreePromotion.new hash[:get_one_free] if hash[:get_one_free]
+ promotion = PackagePromotion.new hash[:package] if hash[:package]
+ promotion = ThresholdPromotion.new hash[:threshold] if hash[:threshold]
+ end
+ promotion
+ end
+end
+
+class Cart
+
+ def initialize(inventory)
+ @cartProducts = Hash.new 0
+ @inventory = inventory
+ @coupon = nil
+ end
+
+ def add(product_name, number = 1)
+ verify_product product_name, number
+ product_to_add = @inventory.get_product product_name
+ @cartProducts[product_to_add] = @cartProducts[product_to_add] + number
+ end
+
+ def total_no_coupons()
+ curr_total = 0
+ @cartProducts.each { |product, count| curr_total += product.get_price(count)}
+ curr_total
+ end
+
+ def total()
+ curr_total = total_no_coupons
+ coupon_discount = coupon_discount curr_total
+ coupon_discount > curr_total ? curr_total = 0 : curr_total -= coupon_discount
+ curr_total
+ end
+
+ def coupon_discount(total)
+ if @coupon
+ coupon_discount = @coupon.details[:amount] if @coupon.details[:amount]
+ percent = @coupon.details[:percent]
+ coupon_discount = total * percent / 100 if percent
+ coupon_discount = total if coupon_discount > total
+ else coupon_discount = 0
+ end
+ coupon_discount
+ end
+
+ def invoice()
+ invoice_s = header
+ @cartProducts.each { |product, count| invoice_s << get_line(product, count)}
+ if @coupon
+ discount = -coupon_discount(total_no_coupons)
+ invoice_s << format("| %-46s |%9.2f |\n", @coupon.coupon_string, discount)
+ end
+ invoice_s << "+------------------------------------------------+----------+\n"
+ invoice_s << format("| %-46s |%9.2f |\n", "TOTAL", total)
+ invoice_s << "+------------------------------------------------+----------+\n"
+ end
+
+ def use(coupon_name)
+ @coupon = @inventory.get_coupon(coupon_name)
+ end
+
+ private
+
+ def header
+ invoice_s = "+------------------------------------------------+----------+\n"
+ invoice_s << "| Name qty | price |\n"
+ invoice_s << "+------------------------------------------------+----------+\n"
+ end
+
+ def verify_product(product_name, number)
+ is_existing = @inventory.contains? product_name
+ product_to_add = @inventory.get_product product_name
+ is_number_ok = (number > 0 and number <= 99)
+ is_number_ok = (is_number_ok and @cartProducts[product_to_add] + number <= 99)
+ unless is_existing and is_number_ok
+ raise "Invalid parameters passed."
+ end
+ end
+
+ def get_line(product, count)
+ format_s = "| %-44s%2d |%9.2f |\n"
+ line = format format_s, product.name, count, product.price * count
+ if product.promotion != nil
+ discount = -product.get_discount(count)
+ discount_string = product.get_discount_string(count)
+ line << format("| %-45s|%9.2f |\n", discount_string, discount)
+ end
+ line
+ end
+end
+
+class Product
+
+ attr_accessor :name, :price, :promotion
+
+ def initialize(name, price, promotion)
+ @name = name
+ @price = price
+ @promotion = promotion
+ end
+
+ def get_price(count)
+ if @promotion
+ price * count - get_discount(count)
+ else price * count
+ end
+ end
+
+ def get_discount(count)
+ @promotion.get_discount(self, count)
+ end
+
+ def get_discount_string(count)
+ if @promotion
+ @promotion.get_discount_string
+ end
+ end
+
+end
+
+class GetOneFreePromotion
+
+ def initialize(nth_free)
+ @nThFree = nth_free
+ end
+
+ def get_discount(product, count)
+ product.price * (count / @nThFree)
+ end
+
+ def get_discount_string
+ format "(buy %d, get 1 free)", @nThFree - 1
+ end
+end
+
+class PackagePromotion
+
+ def initialize(hash)
+ @packageSize = hash.keys[0]
+ @discount = hash.values[0]
+ end
+
+ def get_discount(product, count)
+ discount_count = count / @packageSize
+ discount_count * @packageSize * product.price * @discount / 100
+ end
+
+ def get_discount_string
+ format "(get %d%% off for every %d)", @discount, @packageSize
+ end
+end
+
+class ThresholdPromotion
+
+ def initialize(hash)
+ @fullPriceNum = hash.keys[0]
+ @discount = hash.values[0]
+ end
+
+ def get_discount(product, count)
+ discount_count = count > @fullPriceNum ? count - @fullPriceNum : 0
+ discount_count * product.price * @discount / 100
+ end
+
+ def get_discount_string
+ tail = case @fullPriceNum
+ when 1 then "st"
+ when 2 then "nd"
+ when 3 then "rd"
+ else "th"
+ end
+ format "(%d%% off of every after the %d%s)", @discount, @fullPriceNum, tail
+ end
+end
+
+class Coupon
+ attr_accessor :name, :details
+
+ def initialize(name, details)
+ @name = name
+ @details = details
+ end
+
+ def coupon_string
+ discount = if @details[:percent]
+ "#{@details[:percent]}%"
+ else format "%.2f", @details[:amount]
+ end
+ "Coupon #{@name} - #{discount} off"
+ end
+
+end