Я подумал, что, возможно, было бы наиболее полезно предложить, как вы можете реорганизовать свой код, но если это ответит на ваш конкретный вопрос, тем лучше. Если это не так, я полагаю, что кто-то другой сделает это в ближайшее время.
Вы можете использовать выписки по делу, чтобы определить применяемую ставку и скидку, но есть альтернативный способ сделать это.
RATES = [[2, 0.10], [10, 0.20], [40, 0.30], [70, 0.50], [100, 0.75],
[Float::INFINITY, 0.90]]
DISCOUNTS = [[9, 1.0], [39, 0.9], [69, 0.8], [99, 0.7], [Float::INFINITY, 0.6]]
В массиве RATES
указана стоимость доставки книги в зависимости от максимального веса всех книг. Если этот вес меньше 2
(скажем, фунтов), то затраты (скажем, в долларах) составляют 0,10 доллара за книгу. Если общий вес больше, чем 2
, но меньше, чем 10
, стоимость доставки составляет 0,20 доллара и т. Д. Стоимость единицы составляет $0.90
, если общий вес составляет 99
фунтов или более. (Почему эти суммы увеличиваются, я не могу сказать.)
Точно так же, если заказано менее 9
книг, скидка за книгу составляет 1%
;если заказано не менее 9
, но меньше 39
, скидка за книгу составляет 0.9%
и т. д. (Я бы ожидал, что процент скидки будет расти, но кто я такой, чтобы сказать.)
Теперь давайте зададим пользователю несколько вопросов. Мы могли бы создать простой метод для уменьшения количества повторяющегося кода.
def ask(str)
print str
gets.to_f
end
price = ask("Please enter the price of one book: ") #=> 43.12
weight = ask("Please enter the weight of one book: ") #=> 1.45
quantity = ask("Please enter the quantity of books: ") #=> 30.0
Величины справа - это три значения, которые я ввел. Затем вычислите промежуточный итог:
subtotal = price * quantity
#=> 1293.6
Поскольку price
и quantity
являются числами с плавающей точкой, subtotal
также будет числами с плавающей точкой. (На самом деле, если price
было бы с плавающей точкой, а quantity
было целым числом, subtotal
все равно было бы с плавающей точкой.)
Теперь давайте посчитаем стоимость доставки и скидку. Опять же, чтобы избежать повторяющегося кода, давайте создадим простой метод:
def rate_or_discount(arr, amt)
arr.find { |k,v| amt < k }.last
end
total_weight = quantity * weight
#=> 43.5
rate = rate_or_discount(RATES, total_weight)
#=> 0.5
ship_cost = total_weight * rate
#=> 21.75
Вы понимаете, почему 0.5
был возвращен для rate
?
Теперь вычислите скидку, а затем общую стоимость.
discount = 0.01 * rate_or_discount(DISCOUNTS, quantity)
#=> 0.009000000000000001
total_cost = (1 - discount) * subtotal + ship_cost
#=> 1303.7076
Обратите внимание, что (1 - discount)
- это число с плавающей точкой, поскольку discount
- это число с плавающей точкой.
Мы можемТеперь отобразите значения, представляющие интерес.
puts sprintf("Subtotal: $%.2f", subtotal.round(2))
Subtotal: $1293.60
puts sprintf("Shipping: $%.2f", ship_cost.round(2))
Shipping: $21.75
puts sprintf("Total cost: $%.2f", total_cost.round(2))
Total cost: $1303.71
См. Ядро # sprinf для объяснения кодов форматирования, которые я использовал.
Вместо этого можно написать (обратите внимание на символ новой строки):
printf("Subtotal: $%.2f\n", subtotal.round(2))
Subtotal: $1293.60
Если бы я вместо этого написал:
puts "Subtotal: $#{subtotal.round(2)}"
была бы отображена строка
Subtotal: $1293.6
, у которой обнуленный конечный ноль отключен.
См. Также Enumerable # find и Float # round .