Округление чисел в рубине вверх или вниз до ближайших 10/100/1000 другим способом - PullRequest
0 голосов
/ 15 сентября 2018

Короткая версия: другой способ "округления" чисел до удобных для пользователя значений без .round / .floor / .ceil.

Длинная скучная версия: Представьте себе следующие разговоры между продавцом и клиентами:

Продавец: сколько бы вы заплатили за продукт X?Маленький таймер: 15 долларов США СП: Я могу продать его вам за 50 долларов США. ОК: Я могу с этим смириться.

Если бы продавец сказал 100 долларов, маленький таймер сказал бы, что нет, он не может себе этого позволить.,И, очевидно, он не может просто отдать его бесплатно, потому что продавец не благотворительность.

Опять же со средним парнем:

Продавец: сколько бы вы заплатилидля продукта X?Обычный парень: не знаю ... 120 долларов?SP: нет, $ 200 - это минимум, за который мы продали быAG: хорошо, хорошо.

Затем приходит большой папа:

Продавец: сколько бы вы хотели потратить сегодня, сэр?Большой папочка: около 1200 долларов?С.П .: Почему не 1500 долларов?Большой папочка: да, давайте сделаем 1500 долларов.С.П .: Почему не 1650 долларов?Большой папочка: мы могли бы также сделать 2000 долларов.SP: спасибо за ваш бизнес, сэр!

Да, мы знаем, кто есть кто, в том, что касается того, сколько денег может иметь клиент, например, для крупного парня, который, как мы знаем, имеет около 2000- 5000 долларов.на него.

Поэтому я ищу способ разумного, но чувствительного округления цен на товары следующим образом:

15 -> 50 #!
23 -> 50
51 -> 100
71 -> 100
109 -> 100
132 -> 150 
124 -> 150 #!
173 -> 200
399 -> 400
549 -> 500
1231 -> 1500 #!
2761 -> 3000 
3104 -> 3000
3249 -> 3500 #!

В основном округляем цены вверх или вниз, чтобы сделать ихдружественный, но не слишком отклоняющийся от здравого смысла ...

class Price

    def initialize(s = 0) # possibly add customer “size”?
        @price = s
    end

    # operations
    def inc_to(x)
        @price = [@price, x].flatten.max
        self
    end

    def dec_to(x)
        @price = [@price, x].flatten.min
        self
    end

    def inc_with(x)
        @price+=x
        self
    end

    def dec_by(x)
        @price = @price - x
        self
    end

    def avg(x)
        arr = [@price, x]
        @price = arr.inject{ |sum, el| sum + el }.to_f / arr.size
        self
    end

    def round
        #@price = ?
        self
    end

    # getters
    def value
        @price
    end

    def to_i
        @price.to_i
    end

    def to_f
        @price.to_f
    end

end

Я пытался написать этот пример класса, но, похоже, не могу использовать хороший метод .round, оценит любой ввод.

Price.new(15).inc_to(1000).dec_to(700).avg(100).inc_to(200).inc_to(400).dec_to(351).inc_with(48).value # .round.to_i

1 Ответ

0 голосов
/ 15 сентября 2018

Невозможно обработать ввод, как вы хотите, с помощью универсального метода округления из-за противоречивых правил (вы хотите, чтобы 51 было «округлено» до 100, а другие смещены вниз.)

Я бы пошел с получением хеша или пар RangePrice:

rounds = {
  (0..50) => 50,
  (51..110) => 100,
  (111..165) => 150,
  (166..220) => 200,
  ...
  (700..1200) => 1000,
  (1201..1600) => 1500,
  ...
  (4200..7000) => 5000      
}

, а затем просто сделайте detect:

rounds.detect { |range, _| range === price }.last
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...