Unix wayΒΆ

sched:

#!/usr/bin/env python2

import sys

# return how many minutes t2 is ahead of t1
def diff_time((t1h, t1m), (t2h, t2m)):
    hd = t2h - t1h
    md = t2m - t1m
    diff = hd * 60 + md
    # wrap around
    if diff < -720:
        diff += 1440
    return diff

def get_entries(time, filename):
    now_hr, now_minute = [int(n) for n in time.split(':')]

    entries = list()
    with open(filename, 'r') as f:
        for line in f:
            route, startnr, hr, mn = [int(n) for n in line.split(' ')]
            dt = diff_time((now_hr, now_minute), (hr, mn))
            if dt > 0:
                entries.append((route, startnr, dt, hr, mn))

    entries.sort(key=lambda (r, s, dt, hr, mn): dt)

    return entries[:50]

def main():
    time = sys.argv[1]
    filename = sys.argv[2]

    entries = get_entries(time, filename)
    for (r, s, dt, th, tm) in entries:
        print r, s, th, tm, 1

    test()

def test():
    assert diff_time((6, 34), (6, 40)) == 6
    assert diff_time((6, 40), (6, 34)) != 6

if __name__ == '__main__':
    main()

parse_gps:

#!/usr/bin/env python2

# input format: generated by gps.py:
# <route nr> <start nr> <gps x> <gps y> <flag already passed or not>

# output format: as by sched.py:
# several rows of:
# <route nr> <start nr> <hr> <min> 0
# for all that have passed:
# <route nr> <start nr> 0 0 2

import sys
import math

def dist(a, b):
    return math.sqrt(((a[0] - b[0]) ** 2) + ((a[1] - b[1]) ** 2))

def parse_historical_data(filename):
    ret = list()
    with open(filename, 'r') as f:
        for line in f:
            l = line.split(' ')
            routenr = int(l[0])
            t = float(l[1])
            px = float(l[2])
            py = float(l[3])
            ret.append((routenr, t, px, py))
    return ret

def get_running_buses(filename, hist):
    buses = list()
    passed_buses = list()
    with open(filename, 'r') as f:
        for line in f:
            l = line.split(' ')[:5]
            routenr = int(l[0])
            startnr = int(l[1])
            gx = float(l[2])
            gy = float(l[3])
            passed = l[4].strip() == '2'

            if passed:
                passed_buses.append((routenr, startnr))
            else:
                times = list()
                for bus_routenr, t, px, py, in hist:
                    if bus_routenr != routenr:
                        continue
                    d = dist((px, py), (gx, gy))
                    if d < 100.0:
                        times.append(t)
                if times:
                    avgtime = sum(times) / float(len(times))
                    this_bus = (routenr, startnr, avgtime)
                    buses.append(this_bus)

    buses.sort(key=lambda (r, s, t): t)
    return buses, passed_buses

def main():
    # parse arguments
    time = sys.argv[1]
    now_hr, now_minute = [int(n) for n in time.split(':')]
    current_gps = sys.argv[2]
    historical_gps = sys.argv[3]

    # parse the data
    historical_data = parse_historical_data(historical_gps)
    running_buses, passed_buses = get_running_buses(current_gps, historical_data)

    # output
    for routenr, startnr, time in running_buses[:20]:
        h = now_hr
        m = int(now_minute + time)
        while m >= 60:
            m -= 60
            h += 1
        if h > 23:
            h -= 24
        print routenr, startnr, h, m, 0

    for routenr, startnr in passed_buses:
        print routenr, startnr, 0, 0, 2

if __name__ == '__main__':
    main()

merge:

#!/usr/bin/env python2

# usage: merge.py "This is my stop" 10:34 gps_info.txt sched_info.txt > label_info.txt

import sys
import sched_ex

route_names = {
        3:   'Park Street',
        29:  'Central Park',
        848: 'Wall Street',
        6:   'Manhattan Square',
        72:  'Hill Street'}

class Kind(object):
    GPS = 0
    Schedule = 1
    Passed = 2

def int_to_kind(n):
    for i in [Kind.Schedule, Kind.GPS, Kind.Passed]:
        if n == i:
            return n
    raise RuntimeError('No Kind')

class BusInfo(object):
    def __init__(self, routenr, startnr, hour, minute, kind):
        self.routenr = routenr
        self.startnr = startnr
        self.hour = hour
        self.minute = minute
        self.kind = int_to_kind(kind)

def parse_data(now, files):
    ret = list()
    for fn in files:
        with open(fn, 'r') as f:
            for line in f:
                routenr, startnr, hr, minute, kind = [int(n) for n in line.split()]
                ret.append(BusInfo(routenr, startnr, hr, minute, kind))

    passed = set([(bi.routenr, bi.startnr) for bi in ret if bi.kind == Kind.Passed])
    have_gps_data = set([(bi.routenr, bi.startnr) for bi in ret if bi.kind == Kind.GPS])
    ret = [bi for bi in ret if (bi.routenr, bi.startnr) not in passed]
    ret = [bi for bi in ret if (bi.routenr, bi.startnr) not in have_gps_data or bi.kind == Kind.GPS]
    ret.sort(key=lambda bi: sched_ex.diff_time(now, (bi.hour, bi.minute)))
    return ret

def main():
    now = [int(n) for n in sys.argv[2].split(':')]
    files = sys.argv[3:5]
    data = parse_data(now, files)

    print sys.argv[1]
    print sys.argv[2]
    for bi in data[:7]:
        print bi.routenr
        print route_names[bi.routenr]
        if bi.kind == Kind.Schedule:
            print 'ca.',
        print '%02d:%02d' % (bi.hour, bi.minute)

if __name__ == '__main__':
    main()