You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
9.9 KiB

2 years ago
#! /usr/bin/env ruby
require 'json'
$datestr = ARGV[0] || $stdin.gets.strip
# @param [String] station_name
def normalize_station station_name
station_name
.downcase
.gsub(/\s/, ' ')
.gsub('ă', 'a')
.gsub('â', 'a')
.gsub('î', 'i')
.gsub('ș', 's')
.gsub('ț', 't')
end
def get_station station_name
# Try getting from file
begin
JSON.parse(File.read(File.join($datestr, 'stations', "#{normalize_station(station_name)}.json")), symbolize_names: true)
rescue
nil
end
end
# @param [String] train_number
def get_train train_number
# Try getting from file
begin
JSON.parse(File.read(File.join($datestr, 'trains', "#{train_number}.json")), symbolize_names: true)
rescue
nil
end
end
visited_stations = Dir.entries(File.join $datestr, 'stations')
.filter { |entry| entry != '.' and entry != '..' }
.map { |name| if name.end_with? ".json" then name[0...-5] else name end }
.map { |name| get_station(name)[:stationName] }
visited_trains = Dir.entries(File.join $datestr, 'trains')
.filter { |entry| entry != '.' and entry != '..' }
.map { |name| if name.end_with? ".json" then name[0...-5] else name end }
trains = visited_trains.map { |train_number| get_train train_number }
r_trains = trains.filter { |train| train[:rank] == 'R' }
re_trains = trains.filter { |train| train[:rank] == 'R-E' }
ir_trains = trains.filter { |train| train[:rank] == 'IR' }
irn_trains = trains.filter { |train| train[:rank] == 'IRN' }
ic_trains = trains.filter { |train| train[:rank] == 'IC' }
def filter_by_arrival_delay trains
trains.filter do |train|
arrival_station = train[:groups][0][:stations][-1]
arrival = arrival_station[:arrival]
if arrival[:status] and arrival[:status][:real]
yield arrival[:status][:delay]
else
false
end
end
end
def get_early_arrival trains
filter_by_arrival_delay(trains) { |delay| delay < 0 }
end
def get_on_time_arrival trains
filter_by_arrival_delay(trains) { |delay| delay == 0 }
end
def get_late_arrival trains
filter_by_arrival_delay(trains) { |delay| delay > 0 }
end
def get_late_gt5_arrival trains
filter_by_arrival_delay(trains) { |delay| delay > 5 }
end
on_time_departure = trains.filter do |train|
departure_station = train[:groups][0][:stations][0]
departure = departure_station[:departure]
departure[:status] and departure[:status][:real] and departure[:status][:delay] == 0
end
late_departure = trains.filter do |train|
departure_station = train[:groups][0][:stations][0]
departure = departure_station[:departure]
departure[:status] and departure[:status][:real] and departure[:status][:delay] > 0
end
early_arrival = get_early_arrival trains
on_time_arrival = get_on_time_arrival trains
late_arrival = get_late_arrival trains
late_arrival_gt5 = get_late_gt5_arrival trains
late_gt5_arrival = late_arrival_gt5
gained_delay = []
recovered_delay = []
early_on_route = []
ongoing = trains.filter do |train|
arrival_station = train[:groups][0][:stations][-1]
arrival_station[:arrival][:status] and not arrival_station[:arrival][:status][:real]
end
arrival_delays = {}
trains.each do |train|
arrival_station = train[:groups][0][:stations][-1]
arrival = arrival_station[:arrival]
if arrival[:status] and arrival[:status][:real]
delay = arrival[:status][:delay]
arr = arrival_delays.fetch(delay, [])
arr << train
arrival_delays[delay] = arr
end
end
puts "#{on_time_departure.count} trains departed on time"
puts "#{late_departure.count} trains departed late"
puts
printf "%d trains arrived early\n", early_arrival.count
# printf " %4d (%3d%%) R, %4d (%3d%%) R-E, %4d (%3d%%) IR, %4d (%3d%%) IRN, %4d (%3d%%) IC\n", get_early_arrival(r_trains).count, (get_early_arrival(r_trains).count * 100 / early_arrival.count), get_early_arrival(re_trains).count, (get_early_arrival(re_trains).count * 100 / early_arrival.count), get_early_arrival(ir_trains).count, (get_early_arrival(ir_trains).count * 100 / early_arrival.count), get_early_arrival(irn_trains).count, (get_early_arrival(irn_trains).count * 100 / early_arrival.count), get_early_arrival(ic_trains).count, (get_early_arrival(ic_trains).count * 100 / early_arrival.count)
printf "%d trains arrived on time\n", on_time_arrival.count
# printf " %4d (%3d%%) R, %4d (%3d%%) R-E, %4d (%3d%%) IR, %4d (%3d%%) IRN, %4d (%3d%%) IC\n", get_on_time_arrival(r_trains).count, (get_on_time_arrival(r_trains).count * 100 / on_time_arrival.count), get_on_time_arrival(re_trains).count, (get_on_time_arrival(re_trains).count * 100 / on_time_arrival.count), get_on_time_arrival(ir_trains).count, (get_on_time_arrival(ir_trains).count * 100 / on_time_arrival.count), get_on_time_arrival(irn_trains).count, (get_on_time_arrival(irn_trains).count * 100 / on_time_arrival.count), get_on_time_arrival(ic_trains).count, (get_on_time_arrival(ic_trains).count * 100 / on_time_arrival.count)
printf "%d trains arrived late\n", late_arrival.count
# printf " %4d (%3d%%) R, %4d (%3d%%) R-E, %4d (%3d%%) IR, %4d (%3d%%) IRN, %4d (%3d%%) IC\n", get_late_arrival(r_trains).count, (get_late_arrival(r_trains).count * 100 / late_arrival.count), get_late_arrival(re_trains).count, (get_late_arrival(re_trains).count * 100 / late_arrival.count), get_late_arrival(ir_trains).count, (get_late_arrival(ir_trains).count * 100 / late_arrival.count), get_late_arrival(irn_trains).count, (get_late_arrival(irn_trains).count * 100 / late_arrival.count), get_late_arrival(ic_trains).count, (get_late_arrival(ic_trains).count * 100 / late_arrival.count)
printf "%d trains arrived with a delay greater than 5 minutes\n", late_arrival_gt5.count
# printf " %4d (%3d%%) R, %4d (%3d%%) R-E, %4d (%3d%%) IR, %4d (%3d%%) IRN, %4d (%3d%%) IC\n", get_late_gt5_arrival(r_trains).count, (get_late_gt5_arrival(r_trains).count * 100 / late_gt5_arrival.count), get_late_gt5_arrival(re_trains).count, (get_late_gt5_arrival(re_trains).count * 100 / late_gt5_arrival.count), get_late_gt5_arrival(ir_trains).count, (get_late_gt5_arrival(ir_trains).count * 100 / late_gt5_arrival.count), get_late_gt5_arrival(irn_trains).count, (get_late_gt5_arrival(irn_trains).count * 100 / late_gt5_arrival.count), get_late_gt5_arrival(ic_trains).count, (get_late_gt5_arrival(ic_trains).count * 100 / late_gt5_arrival.count)
puts
puts "Arrivals at destination by rank:"
printf " R: %4d (%3d%%) early, %4d (%3d%%) on time, %4d (%3d%%) late [%4d (%3d%%) >5min late], %4d total\n", get_early_arrival( r_trains).count, (get_early_arrival( r_trains).count * 100 / r_trains.count), get_on_time_arrival( r_trains).count, (get_on_time_arrival( r_trains).count * 100 / r_trains.count), get_late_arrival( r_trains).count, (get_late_arrival( r_trains).count * 100 / r_trains.count), get_late_gt5_arrival( r_trains).count, (get_late_gt5_arrival( r_trains).count * 100 / r_trains.count), r_trains.count
printf "R-E: %4d (%3d%%) early, %4d (%3d%%) on time, %4d (%3d%%) late [%4d (%3d%%) >5min late], %4d total\n", get_early_arrival( re_trains).count, (get_early_arrival( re_trains).count * 100 / re_trains.count), get_on_time_arrival( re_trains).count, (get_on_time_arrival( re_trains).count * 100 / re_trains.count), get_late_arrival( re_trains).count, (get_late_arrival( re_trains).count * 100 / re_trains.count), get_late_gt5_arrival( re_trains).count, (get_late_gt5_arrival( re_trains).count * 100 / re_trains.count), re_trains.count
printf " IR: %4d (%3d%%) early, %4d (%3d%%) on time, %4d (%3d%%) late [%4d (%3d%%) >5min late], %4d total\n", get_early_arrival( ir_trains).count, (get_early_arrival( ir_trains).count * 100 / ir_trains.count), get_on_time_arrival( ir_trains).count, (get_on_time_arrival( ir_trains).count * 100 / ir_trains.count), get_late_arrival( ir_trains).count, (get_late_arrival( ir_trains).count * 100 / ir_trains.count), get_late_gt5_arrival( ir_trains).count, (get_late_gt5_arrival( ir_trains).count * 100 / ir_trains.count), ir_trains.count
printf "IRN: %4d (%3d%%) early, %4d (%3d%%) on time, %4d (%3d%%) late [%4d (%3d%%) >5min late], %4d total\n", get_early_arrival(irn_trains).count, (get_early_arrival(irn_trains).count * 100 / irn_trains.count), get_on_time_arrival(irn_trains).count, (get_on_time_arrival(irn_trains).count * 100 / irn_trains.count), get_late_arrival(irn_trains).count, (get_late_arrival(irn_trains).count * 100 / irn_trains.count), get_late_gt5_arrival(irn_trains).count, (get_late_gt5_arrival(irn_trains).count * 100 / irn_trains.count), irn_trains.count
printf " IC: %4d (%3d%%) early, %4d (%3d%%) on time, %4d (%3d%%) late [%4d (%3d%%) >5min late], %4d total\n", get_early_arrival( ic_trains).count, (get_early_arrival( ic_trains).count * 100 / ic_trains.count), get_on_time_arrival( ic_trains).count, (get_on_time_arrival( ic_trains).count * 100 / ic_trains.count), get_late_arrival( ic_trains).count, (get_late_arrival( ic_trains).count * 100 / ic_trains.count), get_late_gt5_arrival( ic_trains).count, (get_late_gt5_arrival( ic_trains).count * 100 / ic_trains.count), ic_trains.count
puts
puts "Delays at arrival:"
arrival_delays.to_a.sort {|a, b| b[1].count <=> a[1].count}.each do |delay, trains|
printf "%3d min: %4d train%s", delay, trains.count, if trains.count == 1 then " " else "s" end
if trains.count <= 5
printf " (%s)", trains.map { |train|
sprintf "%3s %5s", train[:rank], train[:number]
}.join(", ")
end
puts
end
puts
puts "#{ongoing.count} trains still travelling"
puts
puts "#{on_time_departure.count} trenuri plecate la timp"
puts "#{late_departure.count} trenuri plecate cu întârziere"
puts
puts "#{early_arrival.count} trenuri sosite mai devreme"
puts "#{on_time_arrival.count} trenuri sosite la timp"
puts "#{late_arrival.count} trenuri sosite cu întârziere"
puts "#{late_arrival_gt5.count} trenuri sosite cu întârziere mai mare de 5 minute"
puts
puts "Întârzieri la destinație:"
arrival_delays.to_a.sort {|a, b| b[1].count <=> a[1].count}.each do |delay, trains|
printf "%3d min: %4d tren%s", delay, trains.count, if trains.count == 1 then " " else "uri" end
if trains.count <= 5
printf " (%s)", trains.map { |train|
sprintf "%3s %5s", train[:rank], train[:number]
}.join(", ")
end
puts
end