Skip to content

Instantly share code, notes, and snippets.

@bibendi
Last active July 19, 2016 07:34
Show Gist options
  • Save bibendi/d3facbc772b1cb6cf9872c7e3ecfb7c1 to your computer and use it in GitHub Desktop.
Save bibendi/d3facbc772b1cb6cf9872c7e3ecfb7c1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# coding: utf-8
gem "activesupport"
gem "optparse-range"
gem "tty-table"
gem "ascii_charts"
require "optparse"
require "optparse/time"
require "optparse/range"
require "active_support/all"
require "tty-table"
require "ascii_charts"
options = {}
opt_parser = OptionParser.new do |opt|
opt.banner = 'Usage: cosorter OPTIONS'
opt.separator ''
opt.separator 'Options'
opt.on('-h', '--help', 'Help') do
puts opt_parser
exit
end
opt.on('--ids x,y,z', Array, 'Product ids') do |value|
options[:ids] = value.map(&:to_i)
end
opt.on('--start DATE', Time, 'Start time') do |value|
options[:start] = value
end
opt.on('--duration DAYS', Integer, 'Number of days (default: 1 day)') do |value|
options[:period] = value.days
end
opt.on('--threshold MINUTES', Integer, 'Threshold (default: 15 minutes)') do |value|
options[:threshold] = value.minutes
end
opt.on('--peak H:M-H:M', OptionParser::TimeRange, 'Calculate ranks only for this daily interval') do |value|
options[:peak] = value
end
opt.on('--chart', 'Draw charts') do
options[:show_chart] = true
end
end
begin
opt_parser.parse!
mandatory = [:ids, :start]
missing = mandatory.select{ |param| options[param].nil? }
raise OptionParser::MissingArgument, missing.join(', ') unless missing.empty?
rescue OptionParser::ParseError => e
puts e
puts opt_parser
exit
end
options[:period] ||= 1.day
options[:threshold] ||= 15.minutes
options[:show_chart] ||= false
def peak_cover?(current_time, peak)
current_peak = Range.new(
current_time.change(hour: peak.begin.hour, min: peak.begin.min),
current_time.change(hour: peak.end.hour, min: peak.end.min)
)
current_peak.cover?(current_time)
end
def calculate(current_time, ids, tty_table)
secs = (current_time - current_time.at_beginning_of_week).to_i.nonzero? || 1
factor = ((Math.cos(secs) + 1) * 360).round + current_time.to_date.cweek
scores = ids.map do |product_id|
Math.cos(product_id.modulo(factor))
end
sorted = scores.sort.uniq.reverse
ranks = scores.map { |e| sorted.index(e) + 1 }
tty_table << [current_time] + ranks
end
def totals(ids, tty_table)
rows = tty_table.rows
totals = []
ids.size.times do |i|
totals << rows.sum { |row| row[i + 1] == 1 ? 1 : 0 }
end
tty_table << ["Total first times"] + totals
all_totals = totals.sum
tty_table << ["Total first times (%)"] + totals.map { |e| (e / all_totals.to_f * 100).round }
end
def chart(ids, tty_table)
ids.each_with_index do |product_id, i|
plots = []
tty_table.rows[0..-3].each_with_index { |row, index| plots << [row[0].hour, row[i + 1]] }
puts AsciiCharts::Cartesian.new(plots, title: product_id.to_s).draw
end
end
current_time = options.fetch(:start)
finish_time = current_time + options.fetch(:period)
ids = options.fetch(:ids)
threshold = options.fetch(:threshold)
only_peak = !options[:peak].nil?
tty_table = TTY::Table.new(header: ["Time"] + ids.map(&:to_s))
while current_time < finish_time
if !only_peak || peak_cover?(current_time, options[:peak])
calculate(current_time, ids, tty_table)
end
current_time += threshold
end
totals(ids, tty_table)
puts tty_table.render(:ascii, alignment: [:center])
chart(ids, tty_table) if options[:show_chart]
@bibendi
Copy link
Author

bibendi commented Jul 18, 2016

27870955 - Первая Строительная База
46814369 - ИнтерМетПром
52062455 - ТД Гефест
38575395 - Стальинвест

@bibendi
Copy link
Author

bibendi commented Jul 18, 2016

# ./cosorter --ids 27870955,46814369,52062455,38575395 --start 2016.07.11 --duration 2 --threshold 15 --peak 10:00-17:00 --chart
+-------------------------+--------+--------+--------+--------+
|          Time           |27870955|46814369|52062455|38575395|
+-------------------------+--------+--------+--------+--------+
|2016-07-11 10:00:00 +0500|   4    |   2    |   1    |   3    |
|2016-07-11 10:15:00 +0500|   3    |   4    |   1    |   2    |
|2016-07-11 10:30:00 +0500|   4    |   2    |   3    |   1    |
|2016-07-11 10:45:00 +0500|   4    |   2    |   3    |   1    |
|2016-07-11 11:00:00 +0500|   3    |   2    |   1    |   4    |
|2016-07-11 11:15:00 +0500|   3    |   2    |   1    |   1    |
|2016-07-11 11:30:00 +0500|   1    |   3    |   2    |   4    |
|2016-07-11 11:45:00 +0500|   4    |   1    |   3    |   2    |
|2016-07-11 12:00:00 +0500|   2    |   4    |   3    |   1    |
|2016-07-11 12:15:00 +0500|   3    |   1    |   4    |   2    |
|2016-07-11 12:30:00 +0500|   2    |   4    |   3    |   1    |
|2016-07-11 12:45:00 +0500|   1    |   3    |   4    |   2    |
|2016-07-11 13:00:00 +0500|   2    |   4    |   3    |   1    |
|2016-07-11 13:15:00 +0500|   1    |   2    |   4    |   3    |
|2016-07-11 13:30:00 +0500|   2    |   1    |   4    |   3    |
|2016-07-11 13:45:00 +0500|   1    |   3    |   4    |   2    |
|2016-07-11 14:00:00 +0500|   1    |   2    |   3    |   4    |
|2016-07-11 14:15:00 +0500|   1    |   3    |   2    |   4    |
|2016-07-11 14:30:00 +0500|   3    |   1    |   2    |   4    |
|2016-07-11 14:45:00 +0500|   2    |   1    |   4    |   3    |
|2016-07-11 15:00:00 +0500|   1    |   2    |   4    |   3    |
|2016-07-11 15:15:00 +0500|   3    |   4    |   2    |   1    |
|2016-07-11 15:30:00 +0500|   2    |   3    |   4    |   1    |
|2016-07-11 15:45:00 +0500|   3    |   1    |   2    |   4    |
|2016-07-11 16:00:00 +0500|   4    |   1    |   3    |   2    |
|2016-07-11 16:15:00 +0500|   1    |   4    |   3    |   2    |
|2016-07-11 16:30:00 +0500|   1    |   4    |   2    |   3    |
|2016-07-11 16:45:00 +0500|   1    |   4    |   3    |   2    |
|2016-07-11 17:00:00 +0500|   1    |   3    |   2    |   4    |
|2016-07-12 10:00:00 +0500|   4    |   3    |   1    |   2    |
|2016-07-12 10:15:00 +0500|   1    |   4    |   2    |   3    |
|2016-07-12 10:30:00 +0500|   3    |   2    |   4    |   1    |
|2016-07-12 10:45:00 +0500|   2    |   4    |   1    |   3    |
|2016-07-12 11:00:00 +0500|   2    |   1    |   3    |   4    |
|2016-07-12 11:15:00 +0500|   4    |   2    |   3    |   1    |
|2016-07-12 11:30:00 +0500|   3    |   4    |   1    |   2    |
|2016-07-12 11:45:00 +0500|   2    |   4    |   3    |   1    |
|2016-07-12 12:00:00 +0500|   3    |   4    |   2    |   1    |
|2016-07-12 12:15:00 +0500|   4    |   2    |   1    |   3    |
|2016-07-12 12:30:00 +0500|   1    |   3    |   4    |   2    |
|2016-07-12 12:45:00 +0500|   3    |   2    |   1    |   4    |
|2016-07-12 13:00:00 +0500|   4    |   1    |   3    |   2    |
|2016-07-12 13:15:00 +0500|   4    |   2    |   3    |   1    |
|2016-07-12 13:30:00 +0500|   1    |   2    |   3    |   4    |
|2016-07-12 13:45:00 +0500|   1    |   3    |   2    |   4    |
|2016-07-12 14:00:00 +0500|   1    |   4    |   2    |   3    |
|2016-07-12 14:15:00 +0500|   2    |   4    |   1    |   3    |
|2016-07-12 14:30:00 +0500|   2    |   4    |   1    |   3    |
|2016-07-12 14:45:00 +0500|   2    |   1    |   3    |   4    |
|2016-07-12 15:00:00 +0500|   1    |   4    |   3    |   2    |
|2016-07-12 15:15:00 +0500|   3    |   4    |   1    |   2    |
|2016-07-12 15:30:00 +0500|   2    |   3    |   1    |   4    |
|2016-07-12 15:45:00 +0500|   1    |   4    |   3    |   2    |
|2016-07-12 16:00:00 +0500|   1    |   3    |   2    |   4    |
|2016-07-12 16:15:00 +0500|   3    |   1    |   2    |   4    |
|2016-07-12 16:30:00 +0500|   2    |   3    |   4    |   1    |
|2016-07-12 16:45:00 +0500|   3    |   2    |   1    |   4    |
|2016-07-12 17:00:00 +0500|   2    |   3    |   1    |   4    |
|    Total first times    |   19   |   11   |   15   |   14   |
|  Total first times (%)  |   32   |   19   |   25   |   24   |
+-------------------------+--------+--------+--------+--------+

                                                                                    27870955

4| *     *  *           *                                                  *              *              *           *        *  *
3|    *        *  *           *                          *        *     *                       *           *     *        *                             *           *     *
2|                         *     *     *     *              *        *                             *  *        *                             *  *  *        *           *     *
1|                   *              *     *     *  *  *        *              *  *  *  *     *                          *           *  *  *           *        *  *
0+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17


                                                                                    46814369

4|    *                    *     *     *                          *           *  *  *        *     *        *  *  *                       *  *  *     *  *     *
3|                   *              *           *     *              *                 *  *                             *              *                    *     *     *     *
2| *     *  *  *  *                       *        *           *                                *        *           *     *     *  *                                      *
1|                      *     *              *           *  *           *  *                          *                       *                    *                 *
0+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17


                                                                                    52062455

4|                            *     *     *  *  *           *  *     *                          *                       *                                               *
3|       *  *           *  *     *     *           *                       *  *     *                 *  *     *              *  *  *              *  *        *
2|                   *                                *  *        *     *        *     *     *                    *                    *  *                       *  *
1| *  *        *  *                                                                       *        *        *        *     *                 *  *        *  *              *  *
0+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17


                                                                                    38575395

4|             *     *                             *  *  *              *              *              *                    *        *  *           *        *     *  *     *  *
3| *                                      *  *              *  *                 *           *     *                 *                    *  *  *
2|    *                 *     *     *           *                          *  *     *     *                 *           *     *                       *  *     *
1|       *  *     *        *     *     *                          *  *                          *        *     *  *              *                                      *
0+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment