Воскресенье, 27 сентября 2020 14:04

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

Оцените материал
(3 голосов)

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

 

Новый год в СССР. Ностальгия.
Новый год в СССР. Ностальгия.

 

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

 

Dev banner 3

 

Считать биоритмы будем, исходя из формулы:
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])

 

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

 

Блог на рельсах. Live Demo.

 

<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]

    },

Последнее изменениеСуббота, 11 марта 2023 06:44

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

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

Web Development Masterpro

Read more

Заказать сайт

Веб-разработка. Заказать сайт

Вы можете заказать сайт-визитку, блог, корпоративный сайт, интернет-магазин или коммерческий web-портал.