Sign in

Зарегистрируйтесь, чтобы стать полноправным участником сообщества Masterpro.ws.

Пишем счетчик биоритмов на Ruby

Попробовал поискать на гитхабе по слову biorhythm... хм, не нашел ни одного решения ни под Ruby, ни под Ruby on Rails.

Пишем счетчик биоритмов на Ruby
Пишем счетчик биоритмов на Ruby

Странно. Вне зависимости от того, являетесь ли вы сторонником теории биоритмов или нет, решение данной задачки вполне способно представлять интерес, особенно для студентов-абитуриентов... ну ок, пусть будет хотя б одно.

Считать биоритмы будем, исходя из формулы:
B = (sin(2π*t/P))*100%

, где
P = {23,28,33},
B — искомые состояния биоритма (%),
t — количество дней, прошедших с даты рождения до текущего момента.

После некоторых меланхоличных размышлений приходим к вот такому классу, naming которого говорит (надеюсь) сам за себя:

 

class BiorhythmsCalc
  def self.get_values_and_dates(b)
    values = []
    [23, 28, 33].each do |x|
      values << BiorhythmsCalc.biorhythm_counter(x, todays_date(b))[0]
    end
    dates = BiorhythmsCalc.biorhythm_counter(x = 23, todays_date(b))[1].map { |e| "`#{e}`" }.join(', ')
    [values, dates]
  end

  def self.biorhythm_counter(*args)
    arr1 = []
    arr2 = []
    (-3..15).each do |x|
      arr1 << calculation(x, args[1], args[0])
      arr2 << get_date_period(x)
    end
    [arr1, arr2]
  end

  def self.calculation(*args)
  	(Math.sin(2 * Math::PI * BiorhythmsCalc.day_counter(args[0], args[1].to_date) / args[2]) * 100).round(2)
  end

  def self.get_date_period(x)
  	(Date.today + x).to_formatted_s(:short)
  end

  def self.day_counter(*args)
    Integer(Date.today + args[0] - args[1])
  end

  def self.todays_date(b)
  	Date.strptime(b, '%d-%m-%Y')
  end

  def self.flash_message(b)
    'Today, ' +
      Time.new.strftime('%d of %B, %Y').to_s +
      ', you have lived ' +
      BiorhythmsCalc.day_counter(0, todays_date(b)).to_s +
      ' days.'
  end
end

 

Итак, вызов того или иного метода класса BiorhythmsCalc, с передачей соответствующего параметра (все, что необходимо - дата дня рождения), возвращает массивы дат и значений трех биоритмов; дополнительно можно получить количество дней, прожитых со дня рождения (пригодится для вывода flash-сообщения):

 

arr = BiorhythmsCalc.get_values_and_dates(params[:birthday])
@values = arr[0]
@dates = arr.delete_at(1)
flash.now[:notice] = BiorhythmsCalc.flash_message(params[:birthday])

 

На основе полученных значений строим график и/или таблицу, результаты можно взглянуть на живой демке. В табличке подсвечиваем строки, даты которых приходятся на т. н. "критические дни":

 

<script>
let trs = document.querySelectorAll('tbody>tr')
for (let i=0; i<trs.length-1; i++) {
	let v1 = parseFloat(trs[i].children[1].textContent)
	let v2 = parseFloat(trs[i+1].children[1].textContent)
	let v3 = parseFloat(trs[i].children[2].textContent)
	let v4 = parseFloat(trs[i+1].children[2].textContent)
	let v5 = parseFloat(trs[i].children[3].textContent)
	let v6 = parseFloat(trs[i+1].children[3].textContent)
	if (v1 ==0 || v1*v2 < 0) trs[i].style.background = '#ffcccc'
		if (v3 ==0 || v3*v4 < 0) trs[i].style.background = '#ffcccc'
			if (v5 ==0 || v5*v6 < 0) trs[i].style.background = '#ffcccc'
}
</script>

 

Примечание: для построения графика использован Highcharts. Spline with symbols, предоставляющий возможность, при необходимости, отмечать на графике те или иные точки, в зависимости от условий. Воспользуйтесь этим свойством скрипта, если сочтете необходимым:

 

data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, {
            y: 26.5,
            marker: {
                symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)'
            }
        }, 23.3, 18.3, 13.9, 9.6]

    },

Оставить комментарий

Добавьте ваш комментарий