]> jaekl.net Git - oct_sched.git/blob - lib/stats.rb
Add monthly summary report
[oct_sched.git] / lib / stats.rb
1 # frozen_string_literal: true
2
3 require "sqlite3"
4
5 require "database"
6 require "gtfs"
7 require "pry"
8
9 class Stats
10   # Warning:  doesn't account for leap years
11   #                     J   F   M   A   M   J   J   A   S   O   N   D
12   DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
13
14   def initialize
15     @db = Database.new.db
16     @gtfs = Gtfs.new
17   end
18
19   def report(year:)
20     route_totals = {}
21
22     (1..12).each do |month|
23       monthly_totals = report_month(year: year, month: month)
24
25       monthly_totals.each do |route, count|
26         total = route_totals[route] || 0
27         total += count
28         route_totals[route] = total
29       end
30     end
31
32     annual_total = 0
33     route_totals.each do |_route, count|
34       annual_total += count
35     end
36
37     puts "ANNUAL_TOTAL;#{annual_total};#{route_totals.inspect}"
38   end
39
40   def route_origin_stop_ids
41     @route_origin_stop_ids ||= @db.query(
42       "SELECT stop_id FROM stop_times WHERE stop_sequence=1 GROUP BY 1 ORDER BY 1;"
43     ).to_a.flatten
44   end
45
46   # Returns a hash of route_num => trip_count for the given date
47   def trip_counts(date_hash: nil)
48     result = {}
49
50     print "Checking for trips on #{date_hash[:year]}-#{date_hash[:month]}-#{date_hash[:day]}"
51
52     route_origin_stop_ids.each do |stop_id|
53       print "."
54       $stdout.flush
55
56       route_trips = @gtfs.trips(stop_id: stop_id, date_hash: date_hash, originating_only: true).map do |k, v|
57         [
58           k.first,
59           v.map do |x|
60             x.first
61           end,
62         ]
63       end.to_h.each do |route, trips|
64         count = result[route] || 0
65         count += trips.count
66         result[route] = count
67       end
68     end
69     puts " done."
70
71     result
72   end
73
74   def report_month(year:, month:)
75     monthly_totals = {}
76
77     last_day = DAYS_IN_MONTH[month]
78     last_day += 1 if (month == 2) && (0 == year % 4) # leap year (doesn't account for 1900, 2100, ...)
79
80     (1..last_day).each do |day|
81       date_hash = {year: year, month: month, day: day}
82       date_string = "#{year}-#{month.to_s.rjust(2, "0")}-#{day.to_s.rjust(2, "0")}"
83
84       counts = trip_counts(date_hash: date_hash)
85
86       daily_total = 0
87       counts.each do |route, count|
88         route_total = monthly_totals[route] || 0
89         route_total += count
90         monthly_totals[route] = route_total
91
92         daily_total += count
93       end
94
95       puts "#{date_string};#{daily_total};#{counts.inspect}"
96     end
97
98     monthly_totals
99   end
100 end